il database automatico si riempie nei test di script sql

2

Il problema

Sto lavorando su un'applicazione con ~ 1000 tabelle in un database SQL Server. Sto riscontrando un problema ricorrente con uno script sql.

Lo script viene utilizzato dal team di consulenti per "pulire" parte del database e talvolta fallisce perché una nuova tabella con un vincolo di chiave esterna è stata aggiunta qualche mese fa e fino a questo momento nessuno ha eseguito lo script con qualsiasi dato in questa nuova tabella. Viene sollevata una violazione di chiave esterna e tutti gridano agli sviluppatori per i loro strumenti scadenti.

Esiste un test CI su questo script, ma nessuno aggiorna i dati forniti nel test. Quindi il test non fallisce mai perché le nuove tabelle sono lasciate vuote, ma lo script non riesce ancora negli ambienti reali.

La possibile soluzione

Vorrei assicurarmi che ogni tabella nel database contenga almeno alcune righe quando viene eseguito il test dell'interfaccia dello script. Potrei provare a mantenere uno script manuale per riempire i dati e aggiungere un test che controlli che ogni tabella contenga alcune righe ma temo che sarà un incubo di manutenzione.

Un'altra soluzione è quella di avere un altro powershell / sql che lo script analizzi lo schema e crei le righe in base ai tipi di colonna con valori costanti / casuali in tutte le tabelle ordinate utilizzando un ordinamento topologico basato sul grafico delle relazioni delle chiavi esterne. Lo script prima riempirebbe la tabella senza relazioni, quindi le tabelle con le relazioni alle tabelle già piene, ecc.

Ho due domande:

  • questa soluzione sembra ragionevole?
  • sto complicando le cose? c'è un modo più semplice per assicurarsi che uno script sql non fallirà a causa di violazioni dei vincoli di chiave esterna?

Ho controllato gli strumenti esistenti ma gli strumenti di analisi statica non sembrano avere le caratteristiche richieste e gli strumenti di generazione dei dati sono usati per specificare dati "realistici" di cui non mi importa.

    
posta Simon 25.09.2015 - 15:27
fonte

3 risposte

3

Devi rimetterlo sugli sviluppatori che stanno infrangendo l'SQL. Sono nella posizione migliore per aggiornare l'SQL mentre apportano modifiche che sono fresche nella loro mente.

Il modo più semplice per farlo è utilizzare l'integrazione continua.

Imposta un DB di test. Periodicamente, un server di build CI esaminerà il repository del codice sorgente per i nuovi check-in. Se ne trova uno, esegue la build.

Oltre alla compilazione, la build dovrebbe anche distribuire l'applicazione e testare cose come se producesse un file eseguibile valido, eseguire gli script SQL su un DB di test, ecc.

Durante la compilazione, il DB dovrebbe essere ricostruito (backup, creato da script, qualsiasi cosa sia appropriata). Alcuni processi come una stored procedure creata per questo scopo dovrebbero garantire che i dati siano presenti in tutte le tabelle: ovvero, nessuna tabella è vuota.

Ogni volta che uno sviluppatore verifica una modifica che interrompe lo script SQL, interromperà la compilazione perché una tabella è vuota (nessun dato di test) o la procedura di pulizia non è stata aggiornata, o entrambe le cose. Alla fine, gli sviluppatori dovranno aggiornare SQL quando effettuano il check-in dei loro cambiamenti perché senza una build funzionante, non possono essere distribuiti o testati e vengono pagati per produrre un pezzo funzionale di software .

    
risposta data 25.09.2015 - 15:35
fonte
1

Mi sembra che tu abbia almeno 3 ambienti; dev, ci, e produzione, e che il database di ci ambiente non viene mantenuto in una condizione realistica.

Detto questo, direi che la prima opzione che offri, "Potrei provare a mantenere uno script manuale per riempire i dati" non è ottimale - un server CI dovrebbe essere il più completamente automatizzato possibile, no " manuale "script.

Detto questo, usiamo un processo che crea dati all'inizio di ogni esecuzione di CI. Lo usiamo anche nei nostri ambienti di sviluppo e test ed è responsabilità del team di sviluppo (che nel nostro caso include sia attività di "sviluppo" che di "testing") per mantenerlo aggiornato. Come sviluppatori, spesso (a volte più volte al giorno) cancelliamo il nostro db locale e usiamo questo processo per assicurarci di avere un ambiente valido.

nota: consideriamo che il processo sia tanto importante quanto il codice di test, che è altrettanto importante del codice "reale", quindi è mantenuto e sotto controllo del codice sorgente.

    
risposta data 25.09.2015 - 15:55
fonte
1

Proporrò un modo completamente diverso di fare le cose:

Dovresti avere uno script di "creazione di database" che crea il database da zero, iniziando da uno schema / catalogo completamente vuoto e creando tutte le tabelle, con tutte le relazioni necessarie e tutti i dati iniziali immutabili necessari. I dati iniziali immutabili sono, ad esempio, i giorni della settimana (dom, lun, mar, ecc.) Nella tabella days_of_week.

Questo script deve sempre essere eseguito e controllato insieme al resto del codice (supponendo che si stia utilizzando un altro linguaggio oltre a SQL nel negozio), perché il codice si basa su questo script. In questo modo, gli sviluppatori e i tester possono dimenticare di mantenere i vecchi database e modificarli con modifiche. Il database dovrebbe essere un'entità throw-away, sempre creata da zero e popolata con i dati necessari. Lo stato del tuo sistema è descritto interamente da ciò che è impegnato nel sistema di controllo della versione, ed eviti il costante mal di testa se la versione del database è uguale alla versione dello script di creazione del database e la versione del codice. Inoltre, in questo modo, ogni sviluppatore può avere un'istanza locale del database per scopi di sviluppo e test, sempre gettato via e ricreato ad ogni iterazione del ciclo checkout-sviluppo-test-commit.

Quindi, la mia raccomandazione è di non avere nessuno script che crei dati di test. Ogni test dovrebbe creare temporaneamente i dati di cui ha bisogno per essere eseguito, possibilmente in una transazione che viene sottoposta a rollback anziché essere impegnata, in modo da lasciare il database vuoto, oppure ogni test dovrebbe creare uno schema / catalogo temporaneo, creare il database in esso, riempirlo con i dati, eseguire il test e quindi rilasciare l'intero schema / catalogo. Se il test non è in grado di creare i dati a causa di alcune violazioni dei vincoli, qualcuno ha apportato una modifica allo script di creazione del database e l'ha eseguito senza prima preoccuparsi di eseguire i test. È colpa loro.

Se si vuole davvero avere uno script per la creazione di dati di test, anche questo dovrebbe essere eseguito e controllato insieme allo script di creazione del database e al resto del codice. Funzionerà anche.

Le operazioni dovrebbero conservare qualsiasi database di versioni precedenti di cui abbiano bisogno, ed è un loro problema migrare il contenuto di vecchi database in nuovi database rilasciati dagli sviluppatori.

    
risposta data 25.09.2015 - 17:08
fonte

Leggi altre domande sui tag