Moving Media Linq
Il IterateHelper sembra eccessivo. Il sovraccarico che doesn39t prendere un indice finisce per fare un lavoro molto di più in più (la conversione di callback per lambda che prende indice, tenere un conteggio che non viene mai usato). Capisco riuso it39s, ma it39s una soluzione per semplicemente utilizzando un forloop comunque, quindi dovrebbe essere efficiente. ndash Cameron MacFarland 29 dicembre 08 alle 23:20 Ive ha provato alcune variazioni su questo, e continuo a tornare a questa soluzione ragazzi. Ancora una volta, questo è qualcuno soluzione elses. Ma Ive compilato il codice in una piccola biblioteca, e usarlo abbastanza regolarmente. Im andando a incollare il suo codice qui, per la remota possibilità che il suo sito (blog) cessa di esistere ad un certo punto in futuro. (. Non c'è niente di peggio che vedere un post che dice Ecco la risposta esatta è necessario, Click, e l'URL Morto) ha risposto 17 agosto 10 alla 14: 10I ha recentemente condotto in conflitto con questo e mi ci è voluto un po 'per capire perché. Si scopre che il fatto che stavo costruendo la mia interrogazione in parti usando IEnumerable significa 500k record venivano recuperati (lento), poi raggruppati in memoria. Cambiato per usare IQueryable mentre la costruzione di query, il gruppo è stato eseguito da sul server e ho ricevuto solo una mezza dozzina di righe di conta come mi aspettavo. ndash Dave Downs 20 Maggio 10 presso 18:26 vorrei solo esprimere quanto facilmente la risposta letta. Ho letto tre articoli su google prima di trovare il tuo facilmente comprensibile, super semplice spiegazione delle differenze. Grazie 1 ndash Chev 13 gennaio 11 alle 17:24 Un altro motivo per preferire IEnumerable a IQueryable è che non tutte le operazioni di LINQ sono supportate da tutti i provider LINQ. Quindi, fintanto che si sa che cosa you39re facendo, è possibile utilizzare IQueryable per spingere il maggior numero di query per il provider LINQ (LINQ2SQL, EF, NHibernate, MongoDB, ecc). Ma se si lascia altro codice fare ciò che vuole con il IQueryable you39ll alla fine finiscono in difficoltà perché alcuni codice del client utilizzato da qualche parte un'operazione non supportata. Sono d'accordo con la raccomandazione di non rilasciare IQueryable s quotinto il wildquot oltre il repository o livello equivalente. ndash Avish 2 febbraio 14 a 19:19 La risposta superiore è buona, ma pretende molto parlare di alberi di espressione che spiegano come le due interfacce differenti. Fondamentalmente, ci sono due serie identiche di estensioni LINQ. Dove (), Sum (), count (), FirstOrDefault (), ecc tutti hanno due versioni: una che accetta le funzioni e uno che accetta le espressioni. La firma versione IEnumerable è: Dove (FuncltCustomer, boolgt predicato) La firma versione IQueryable è: Dove (ExpressionltFuncltCustomer, boolgtgt predicato) Youve stato probabilmente utilizzando sia di quelli senza rendersene conto perché entrambi sono chiamati utilizzando la sintassi identiche: per esempio Dove (x GT x. City ltCitygt) funziona sia su IEnumerable e IQueryable Quando si usa dove () su una raccolta IEnumerable, il compilatore passa una funzione compilato a Dove () Quando si utilizza dove () su una collezione IQueryable, il compilatore passa un'espressione albero a Dove (). Un albero di espressione è come il sistema di riflessione, ma per il codice. Il compilatore converte il codice in una struttura di dati che descrive ciò che il codice fa in un formato questo è facilmente digeribile. Perché perdere tempo con questa espressione albero cosa che voglio solo Dove () per filtrare i dati. Il motivo principale è che sia l'EF e Linq2SQL ORM in grado di convertire gli alberi di espressione direttamente nel SQL in cui il codice viene eseguito molto più velocemente. Oh, che suona come un incremento delle prestazioni libero, devo usare AsQueryable () in tutto il luogo in quel caso non IQueryable è utile solo se il provider di dati sottostante può fare qualcosa con esso. La conversione di qualcosa di simile a un normale elenco di IQueryable non vi darà alcun beneficio. Entrambi vi darà esecuzione differita, sì. Come per i quali è preferito sopra l'altro, dipende da ciò che la vostra origine dati di fondo è. Tornando un IEnumerable forzerà automaticamente il runtime di utilizzare LINQ to Objects per interrogare la vostra collezione. Tornando un IQueryable (che implementa IEnumerable, tra l'altro) fornisce la funzionalità in più di tradurre la query in qualcosa che potrebbe funzionare meglio sulla sorgente sottostante (LINQ to SQL, LINQ to XML, etc.). Sì, entrambi usano esecuzione differita. Consente di illustrare la differenza con il profiler di SQL Server. Quando si esegue il codice seguente: In SQL Server Profiler troviamo un comando pari a: Ci vogliono circa 90 secondi per eseguire quel blocco di codice contro una tabella WebLog che ha 1 milione di record. Così, tutti i record della tabella vengono caricati nella memoria come oggetti, e poi con ogni. Dove () sarà un altro filtro in memoria contro questi oggetti. Quando usiamo IQueryable invece di IEnumerable nell'esempio di cui sopra (seconda riga): In Profiler SQL Server troviamo un comando pari a: Ci vogliono circa quattro secondi per eseguire questo blocco di codice utilizzando IQueryable. IQueryable ha una proprietà chiamata Espressione che memorizza un'espressione albero che inizia a essere creato quando abbiamo usato il risultato nel nostro esempio (che si chiama esecuzione differita), e alla fine questa espressione verrà convertito in una query SQL da eseguire sul motore di database . rispose 8 giugno 14 alle 01:11 In termini generali mi sento di raccomandare la seguente: Per tornare IQueryableltT se si desidera attivare lo sviluppatore utilizzando il metodo per raffinare la query ritorni prima dell'esecuzione. Se si desidera trasportare solo un insieme di oggetti per enumerare oltre, basta prendere IEnumerable. Immaginate un IQueryable come quello quello che è, una query per i dati (che si può perfezionare se si vuole) un IEnumerable è un insieme di oggetti (che è già stato ricevuto o è stato creato), su cui è possibile enumerare. risposto 11 aprile 12 al 13:09 quotCan enumerare, quot non quotcan IEnumerable. quot ndash Casey 12 febbraio 14 a 18:23 C'è un post sul blog con breve esempio di codice sorgente su come abuso di IEnumerableltTgt può influire notevolmente le prestazioni delle query LINQ: Entity Framework : IQueryable vs IEnumerable. Se scaviamo più a fondo e guardare nelle fonti, possiamo vedere che ci sono ovviamente diversi metodi di estensione sono Svolte per IEnumerableltTgt: Il primo torna iteratore enumerabile, e la seconda crea domanda tramite il provider di query, specificato nella fonte IQueryable. Molto è stato detto in precedenza, ma ritorno alle origini, in maniera più tecnica: IEnumerable è una collezione di oggetti in memoria che è possibile enumerare - una sequenza in memoria che consente di scorrere (rende modo più semplice per entro ciclo foreach, anche se si può andare con IEnumerator solo). Essi risiedono nella memoria come è. IQueryable è un albero di espressione che andranno tradotti in qualcosa d'altro ad un certo punto con la capacità di enumerare sul risultato finale. Credo che questo è ciò che confonde la maggior parte delle persone. Hanno ovviamente diverse connotazioni. IQueryable rappresenta un albero di espressione (una query, semplicemente) che verrà tradotto in qualcosa di diverso dal fornitore di query sottostante non appena le API di rilascio sono chiamati, come LINQ funzioni di aggregazione (somma, conteggio, ecc) o ToListArray, dizionario. . E oggetti IQueryable implementano anche IEnumerable. IEnumerableltTgt modo che se essi rappresentano una query il risultato di tale query potrebbe essere iterata. Significa IQueryable Non dovete essere solo le query. Il termine giusto è che sono alberi di espressione. Ora, come quelle espressioni vengono eseguiti e che si rivolgono a è tutto fino ai cosiddetti fornitori di query (esecutori espressione possiamo pensare). Nel mondo Entity Framework (cioè che mistico sottostante Fonte, o il fornitore di query) espressioni IQueryable sono tradotti in query T-SQL nativo. NHibernate fa cose simili con loro. È possibile scrivere il proprio uno seguendo le idee abbastanza bene descritti in LINQ: Costruire un collegamento Provider IQueryable, per esempio, e si potrebbe desiderare di avere una API di interrogazione su misura per il tuo negozio di prodotti fornitore di servizi. Quindi, fondamentalmente, gli oggetti IQueryable sono sempre costruiti tutto il percorso lungo fino a quando noi li rilasciamo e dire al sistema di riscriverle in SQL o qualsiasi altra cosa e inviare valle della catena di esecuzione per l'elaborazione in avanti in modo esplicito. Come se per la sua esecuzione differita di una funzione LINQ a reggere il regime di albero di espressione nella memoria e inviarlo in esecuzione solo su richiesta, ogni volta che alcune API sono chiamati contro la sequenza (lo stesso Conte, ToList, etc.). Il corretto utilizzo di entrambi dipende fortemente dalla compiti sei di fronte per il caso specifico. Per il modello repository noto io personalmente optare per la restituzione IList. cioè IEnumerable su liste (indicizzatori e simili). Così è il mio consiglio per usare IQueryable solo all'interno di repository e IEnumerable in nessun'altra parte del codice. Non dire circa le preoccupazioni che testabilità IQueryable rompe e rovina la separazione degli interessi principali. Se si restituisce un'espressione dall'interno repository consumatori possono giocare con il livello di persistenza come vorrebbero. Un po 'oltre alla confusione :) (da una discussione nei commenti)) Nessuno di loro sono oggetti in memoria dal momento che non stanno veri tipi di per sé, stanno indicatori di un tipo - se si desidera andare quel profondo. Ma ha senso (e questo è il motivo per cui anche MSDN si esprime così) di pensare IEnumerables come le collezioni in memoria mentre IQueryables come alberi di espressione. Il punto è che l'interfaccia IQueryable eredita l'interfaccia IEnumerable in modo che se rappresenta una query, i risultati di quella query possono essere enumerati. Enumerazione provoca l'albero di espressione associata a un oggetto IQueryable da eseguire. Quindi, in realtà, non puoi davvero chiamare qualsiasi membro IEnumerable senza avere l'oggetto in memoria. Si otterrà in là se lo fai, in ogni modo, se il suo non è vuoto. IQueryables sono solo domande, non i dati. ha risposto 5 giugno 14 at 16:23 Il commento che IEnumerables sono sempre in memoria non è necesassarily vero. L'interfaccia IQueryable implementa l'interfaccia IEnumerable. A causa di questo, è possibile passare un IQueryable grezzo che rappresenta una query LINQ to SQL a destra in una visione che si aspetta un IEnumerable Si può essere sorpresi di scoprire che il contesto dati è scaduto o che si finisce per incorrere in problemi con MARS ( multiple Active Result sets). ndash Alexander Pritchard 22 gennaio 15 alle 20:13 così, infatti, si can39t davvero chiamare qualsiasi membro IEnumerable senza avere l'oggetto in memoria. Si otterrà in là se lo fai, in ogni modo, se it39s non è vuoto. IQueryables sono solo domande, non i dati. Ma ho davvero vedere il tuo punto. I39m andando aggiungere un commento su questo. ndash Arman McHitarian 4 febbraio 15 a 10:58 AlexanderPritchard nessuno di loro sono oggetti in memoria dal they39re non veri tipi di per sé, they39re marcatori di tipo - se si vuole andare quel profondo. Ma ha senso (e that39s perché anche MSDN si esprime così) di pensare IEnumerables come le collezioni in memoria mentre IQueryables come alberi di espressione. Il punto è che l'interfaccia IQueryable eredita l'interfaccia IEnumerable in modo che se rappresenta una query, i risultati di quella query possono essere enumerati. Enumerazione provoca l'albero di espressione associata a un oggetto IQueryable da eseguire. ndash Arman McHitarian 4 Febbraio 15 alle 11:02 ho recentemente imbattuto in un problema con IEnumrable v. IQueryable. L'algoritmo utilizzato prima eseguita una query IQueryable per ottenere una serie di risultati. Questi sono stati poi passati ad un ciclo foreach, con gli articoli istanziati come una classe EF. Questa classe EF è stato poi utilizzato nella clausola FROM di un LINQ to entità di query, causando il risultato di essere IEnumerable. Im abbastanza nuovo per EF e LINQ per entità, così ci è voluto un po 'per capire che cosa il collo di bottiglia è stato. Utilizzando MiniProfiling, ho trovato la query e quindi convertito tutte le singole operazioni di un singolo IQueryable LINQ per la query entità. Il IEnumerable ha preso 15 secondi ed il IQueryable ha preso 0,5 secondi per l'esecuzione. C'erano tre tabelle coinvolte e, dopo aver letto questo, credo che la query IEnumerable è stato effettivamente formando un prodotto incrociato di tre tavolo e filtrare i risultati. Prova ad utilizzare IQueryables come regola-di-pollice e il profilo del lavoro per apportare le modifiche misurabili. risposto 12 luglio 12 al 20:39 il motivo era che le espressioni IQueryable vengono convertiti in un SQL nativo di EF e vengono eseguiti proprio nel DB, mentre le liste IEnumerable sono oggetti in memoria. Ottengono prelevato dalla DB ad un certo punto quando si chiama funzioni di aggregazione come il Conte, Somma, o qualsiasi A. ed operare in memoria dopo. s IQueryable sono bloccati nella memoria una volta you39ve chiamato uno di questi API, ma in caso contrario, si può passare l'espressione la pila di strati e giocare con i filtri fino alla chiamata API. DAL ben progettato come una buona progettato Repository sarà risolvere questo tipo di problemi) ndash Arman McHitarian 5 giugno 14 alle 15:29 vorrei chiarire un paio di cose a causa apparentemente in conflitto le risposte (che circondano la maggior parte IEnumerable). (1) IQueryable estende l'interfaccia IEnumerable. (È possibile inviare un IQueryable a qualcosa che si aspetta IEnumerable senza errori.) (2) Sia IQueryable e IEnumerable LINQ tentativo lazy loading quando l'iterazione di set di risultati. (Si noti che l'attuazione può essere visto in metodi di estensione di interfaccia per ogni tipo.) In altre parole, IEnumerables non sono esclusivamente in memoria. IQueryables non sono sempre eseguiti sul database. IEnumerable deve caricare le cose in memoria (una volta recuperati, forse pigramente) perché non ha alcun provider di dati astratti. IQueryables si basano su un provider astratta (come LINQ to SQL), anche se questo potrebbe anche essere il fornitore in memoria. (A) l'elenco di record come IQueryable dal contesto EF Recupera. (No records sono in memoria.) (B) Far passare il IQueryable di vista il cui modello è IEnumerable. (Valido. IQueryable estende IEnumerable.) (C) iterare e accedere ai dati stabilisce record, entità figlio e le proprietà dalla vista. (Può causare eccezioni) (1) Il IEnumerable tenta lazy loading e il vostro contesto dati è scaduto. Eccezione generata perché fornitore non è più disponibile. (2) Entity Framework proxy entità sono abilitate (impostazione predefinita), e si tenta di accedere a un oggetto correlato (virtuale) con un contesto dati scaduto. Come (1). (3) Multiple Active Result Sets (MARS). Se si sta scorrere il IEnumerable in un foreach (var disco in resultSet) blocco e contemporaneamente tentare di accedere record. childEntity. childProperty. si può finire con Marte a causa di lazy loading di entrambi i set di dati e l'entità relazionale. Ciò causerà un'eccezione se non è abilitata nella stringa di connessione. Ho scoperto che l'attivazione MARS nella stringa di connessione funziona inaffidabile. Vi suggerisco di evitare MARS meno che non sia ben compresa, ed esplicitamente desiderato. Eseguire la query e dei risultati dei negozi invocando risultante resultSet. ToList () Questo sembra essere il modo più semplice per garantire le vostre entità sono in memoria. Nei casi in cui la si sta accedendo entità correlate, si può ancora bisogno di un contesto dati. O che, o è possibile disattivare i proxy di entità ed esplicitamente includere le entità collegate dal vostro DbSet. La differenza principale tra IEnumerable e IQueryable è su dove viene eseguita la logica del filtro. Uno esegue sul lato client (in memoria) e gli altri esegue sul database. Ad esempio, si può considerare un esempio in cui abbiamo 10.000 record per un utente nel nostro database e diciamo solo 900 fuori che sono utenti attivi, quindi in questo caso se usiamo IEnumerable quindi prima che carica tutti i 10.000 record in memoria e quindi applica il filtro IsActive su di essa che alla fine restituisce i 900 utenti attivi. Mentre invece sullo stesso caso se usiamo IQueryable applicherà direttamente il filtro IsActive sul database che direttamente da lì tornerà 900 utenti attivi. rispose 9 maggio 16 ad 12:03 così che è buono da usare. in quale scenario. ndash Neo 23 gennaio alle 09:08 si può utilizzare sia per la stessa strada, e sono diversa solo nelle prestazioni. IQueryable esegue solo contro la base di dati in modo efficiente. Ciò significa che si crea un intero query di selezione e ottiene solo i record correlati. Ad esempio, vogliamo prendere i primi 10 clienti il cui inizio nome con Nimal. In questo caso la query di selezione verrà generato come selezionare top 10 da parte del Cliente in cui il nome come Nimal. Ma se abbiamo usato IEnumerable, l'interrogazione sarebbe come selezionare dal cliente in cui il nome come Nimal e la top ten sarà filtrata a livello di codice C (si arriva tutti i record dei clienti dalla banca dati e li passa in C). ha risposto 25 marzo 16 a 7:02 Mentre si utilizza LINQ to Entities, è importante capire quando usare IEnumerable e IQueryable. Se usiamo IEnumerable, la query verrà eseguita immediatamente. Se usiamo IQueryable, l'esecuzione della query sarà differito fino l'applicazione richiede l'enumerazione. Ora vediamo quello che dovrebbe essere considerato mentre decidere se utilizzare o IQueryable IEnumerable. Utilizzando IQueryable ti dà la possibilità di creare una query LINQ complessa utilizzando più dichiarazioni senza eseguire la query a livello di database. La query viene eseguita solo quando la query LINQ finale viene enumerato. risposto 10 Luglio 15 in 16:34 Sia IQueryable e l'esecuzione rinviare IEnumerable. La differenza è se il lavoro è fatto nel DB o nella memoria, non quando il suo fatto. ndash Servy 10 luglio 15 alle 16:45 La vostra risposta 2017 Stack Exchange, IncPersonally, penso che la capacità di ammettere e di affrontare i propri errori è un effetto collaterale importante di acquisire esperienza e fiducia come sviluppatore. I can8217t aiutarvi a uscire di 8220Imposter Sindrome Jail8221 di per sé, ma posso dire per gli sviluppatori più giovani che you8217ll essere in grado di essere molto più ottimista circa gli errori che si fanno nella vostra decisione tecnica che una volta a superare pensare che è necessario dimostrare la vostra vale la pena di tutti intorno a te in ogni momento. Questo post potrebbe essere altro che guardarsi l'ombelico, ma I8217d scommessa there8217s qualcosa qui che potrebbe riguardare la maggior parte degli sviluppatori, prima o poi. I8217ve avuto alcuni di questi errori strofinato in faccia questa settimana in modo questo è stato nella mia mente. Un paio di anni fa, avrei detto che il mio più grande errore è stato un fallimento di fornire la documentazione ed esempi adeguati usi. Oggi I8217ll felicemente mettere la Martora. StructureMap. o la documentazione Storyteller contro quasi tutti i progetti OSS, in modo I8217m intenzione di passare ad essere in colpa per quei peccati passati. Don8217t volare da solo su grandi cose che penso it8217s perfettamente possibile lavorare da soli su piccole librerie indipendenti. Se you8217re cercando di fare qualcosa di grande, però, you8217re andando ad avere bisogno di aiuto da altre persone. Idealmente, you8217ll effettiva necessità di aiuto codifica e test, ma ad un minimo you8217ll bisogno di feedback e dispongono di idee da altre persone. Se avete voglia di vedere il vostro progetto di attirare l'utilizzo di considerevoli dimensioni, you8217ll vuole sicuramente altre persone che sono anche investito nel vedere il vostro progetto di successo. I can8217t aiuterà molto qui per quanto riguarda il modo di realizzare l'intero 8220build una vibrante community8221 cosa OSS. Altro che Marten, I8217ve mai stato un grande successo ad aiutare a crescere una comunità attorno uno qualsiasi degli strumenti I8217ve costruito. FubuMVC avuto una grande comunità in un primo momento, ma ho attribuire molto più di Chad Myers e Josh Arnold di ogni altra cosa che ho fatto in quel momento. Pensando che il tempo è lineare Ogni volta che faccio un rilascio StructureMap mi sento come 8220that8217s esso, I8217m finalmente fatto con questa cosa, e posso passare ad altre cose now.8221 ho pensato che la versione 3.0 aveva intenzione di risolvere definitivamente il peggio di StructureMap8217s difetti strutturali e funzionali. Poi venne ASP core, il CoreCLR, e il desiderio di accelerare il nostro tempo applicazione di avvio automatico, così è venuto fuori StructureMap 4.0 8212 e questa volta ero veramente finito, grazie. Solo che io wasn8217t. Gli utenti hanno trovato nuovi bug di casi d'uso I8217d mai prese in considerazione (e wouldn8217t usano comunque, ma sto divagando). Corey Kaylor e ho finito per fare alcune ottimizzazioni delle prestazioni di StructureMap fine dello scorso anno che unclogged alcuni problemi con StructureMap in combinazione con alcuni degli strumenti che utilizziamo. Proprio questo Lunedi ho trascorso 3-4 ore di indirizzamento bug in sospeso e tirare le richieste per far uscire una nuova release. Il mio punto qui è quello di adottare la mentalità che la vostra attività su un progetto OSS è ciclico e non lineare. sistemi software, quadri, o librerie non sono mai stati completati, solo abbandonata. Questo è stato il mio unico grande errore e it8217s davvero una questione di prospettiva. Essere realistici circa Sostenere utenti I8217ve avuto problemi di volta in volta su StructureMap quando mi liquidata sentirsi come ero troppo backlog con le domande degli utenti e problemi con un mix di colpa e frustrazione. Credo che l'unica vera risposta è quella di essere solo realistici su quanto velocemente si può andare in giro a risolvere i problemi degli utenti e voi stessi tagliato un po 'di gioco. La tua famiglia, il tuo posto di lavoro, e si deve essere una priorità più alta rispetto a qualcuno su internet. Edificio presenta troppo presto nel primi giorni di sviluppo Agile abbiamo parlato un po 'di 8220pull8221 contro 8220push8221 approcci per dell'ambito del progetto. Nello stile 8220push8221, si tenta di pianificare in anticipo quali caratteristiche e you8217re infrastrutture andando ad avere bisogno, e costruire quella fuori presto. In uno stile 8220pull8221, si ritarda l'introduzione di nuove infrastrutture o caratteristiche fino there8217s un bisogno dimostrato per questo. La mia esperienza costante negli ultimi dieci anni è stato che le caratteristiche che ho costruito in reazione ad un preciso bisogno su un progetto in corso sul posto di lavoro sono stati molto più successo di idee che inceppata nel mio progetto OSS perché sembrava fresco al momento. Distribuzione preliminare Cercate di non mettere qualcosa là fuori per il consumo da parte di altri, se si haven8217t usò se stessi in situazioni realistiche. Probabilmente ho saltato la pistola sul rilascio Narratore 4.0 e I8217ll bisogno di spingere un nuovo rilascio la prossima settimana per problemi di usabilità e un paio di bug. Tutto questo sforzo si sarebbe potuto evitare se I8217d l'utilizzo dell'apparecchio alpha8217s in più dei miei progetti prima di tagliare il NuGet. D'altra parte, a volte quello che ti serve di più è un feedback da altre persone. Mi chiedo se ho fatto un errore aggiungendo la funzionalità di evento di sourcing in Marten. Il progetto che avevo in mente che avrebbe utilizzato che sul posto di lavoro è stato messo fuori a tempo indeterminato e I8217m non proprio la versione dogfood affatto me stesso. Fortunatamente, molte altre persone sono state usando in scenari realistici e I8217m quasi completamente dipendente su di loro per la ricerca di problemi o suggerire miglioramenti o modifiche API. Credo che la funzionalità migliorerebbe molto più veloce se fossi quella versione dogfood, ma non that8217s accadere in qualunque momento presto. Inadeguata Rassegna di richieste Pull cerco di peccare per eccesso di prendere nelle richieste di pull il più presto possibile, ed è spesso causa problemi lungo la strada. In un certo senso, it8217s più difficile per elaborare il codice da qualcun altro per le nuove funzioni, perché you8217re non come investito nel vedere il vostro senso attraverso le implicazioni e potenziali grattacapi. Vedo una richiesta di pull che arriva con le prove adeguate e tendo a prendere in. Ci sono stati diversi momenti in cui mi sarebbe stato meglio fermarsi e pensare a come si inserisce nel resto del progetto. Io don8217t so quale sia la risposta esatta è qui. Troppo rigorosi requisiti per le richieste di tirare e si won8217t ottenere qualsiasi. Troppo poco svista conduce a voi sostenere qualcuno codice else8217s. Overreach e Hubris Odio dire si shouldn8217t inseguire i tuoi sogni OSS, ma penso che bisogna stare attenti a non sbilanciarsi o prendere in una missione impossibile. Prendendo il mio spettacolare estinzione della fiamma con il progetto FubuMVC come un esempio, credo di aver personalmente commesso questi errori: Essere troppo grandiosa. Un framework di sviluppo web e servizio di autobus del tutto alternativo con i propri concetti di modularità molto al di fuori del mainstream è stata appena mai andare a volare. Credo che you8217re più probabilità di successo con l'essere parte di un ecosistema esistente, piuttosto che cercare di creare un nuovo ecosistema. Credo che I8217m detto è che non solo aren8217t sarà molto molti DHH8217s o John Resig8217s. Costruzione di infrastrutture che wasn8217t direttamente collegato al nucleo del vostro progetto. FubuMVC alla fine incluso il proprio motore di template di progetto, il proprio middleware file statico, un fornitore SAML2, e varie altre funzionalità che avrei potuto tirato dallo scaffale invece di costruire me stesso. Tutta quella roba accessoria ha rappresentato un costo opportunità enorme per me stesso. Basta flat out edificio troppa roba invece di concentrarsi sul miglioramento del nucleo del progetto Mentre questa è una dimostrazione di lavoro sulla mia macchina, cosa che mostra I8217m ecco un approccio concettuale molto presto per la revisione da altre persone nel mio negozio. I8217d amore per avere tutte le risposte su questa cosa. Ho passato un po 'di tempo nel nostro ufficio di Salt Lake City la settimana scorsa parlando con la nostra gente QA circa l'automazione di test in generale e dove selenio fa o doesn8217t in forma nel nostro approccio (desiderato). Gli sviluppatori nel mio negozio utilizzano Selenio un bel po 'di oggi all'interno della nostra suite di Cantastorie accettazione con risultati alterni, ma ora la nostra gente QA mancano di automatizzare alcune delle loro suite di test manuale e calci le gomme sul selenio. Come un follow-up a quelle discussioni, questo post mostra il concetto molto presto per come possiamo utilizzare la funzionalità selenio all'interno delle specifiche Storyteller per la loro e le vostre risposte. Tutto il codice è in Storyteller8217s 4.1 ramo. Demo Specifiche Let8217s iniziare molto grezzo. Let8217s dire che hai una pagina web che ha un tag con un qualche tipo di messaggio di testo utente that8217s nascosto in un primo momento. In cima a quello, let8217s dicono che you8217ve ha due pulsanti sullo schermo con il testo e le specifiche 8220Show8221 8220Hide.8221 un narratore per quel comportamento potrebbe apparire come questo: ei risultati HTML sarebbe simile a questa: Il 3 secondi runtime è per lo più in la creazione e il lancio di una istanza del browser Chrome. Più su questo più tardi. Per implementare questa specifica abbiamo bisogno di due cose, corsi di apparecchio che implementano la nostra lingua desiderata ei dati effettivi specifica in un file Markdown mostrato nella sezione successiva. In questo esempio, ci sarebbe una nuova libreria 8220Storyteller. Selenium8221 che fornisce la base per l'integrazione di selenio in specifiche Storyteller con una comune classe di base 8220ScreenFixture 8221 per Fixture8217s che prendono di mira selenio. Dopo di che, la classe SampleFixture utilizzato nella specifica di cui sopra appare così: Se si stava modificando le specifiche in Storyteller8217s Specification Editor. you8217ll avere una casella a discesa elenca gli elementi in base al nome qualsiasi luogo in cui è necessario specificare un elemento in questo modo: Infine, il pacchetto proposto Storyteller. Selenium aggiunge le informazioni per la registrazione delle prestazioni per quanto tempo una pagina web necessario per caricare. Questo è il momento in base alle WebDriver e shouldn8217t essere utilizzato per l'ottimizzazione delle prestazioni dettagliate, ma it8217s ancora un certo numero utile per capire i problemi di prestazioni durante Storyteller specifiche esecuzioni. Vedere la linea 8220Navigationsimple. htm8221 qui sotto: Che cosa significa l'aspetto attuale specifica come Se autore della specifica di cui sopra nell'interfaccia utente Narratore, you8217d ottenere questo file Markdown: Tuttavia, se si stesse scrivendo la specifica a mano direttamente nel file markdown, è può semplificare in questo modo: We8217re cercando molto difficile con Storyteller 4 per rendere le specifiche più facile da scrivere per i non-sviluppatori e quello che vedete qui sopra è un prodotto di questo sforzo. Perché Storyteller Selenio invece di selenio motivo per cui si desidera utilizzare Storyteller e selenio insieme invece di selenio per sé un paio di ragioni: There8217s molto più in corso di test automatizzati efficaci oltre a guidare i browser web (creazione di dati di sistema, il controllo dei dati di sistema , startingstopping il sistema in prova). Storyteller fornisce molte più funzionalità di selenio per sé. It8217s molto prezioso per esprimere test automatizzati in un linguaggio di alto livello con qualcosa come Narratore o cetriolo invece di andare a destra verso il basso per gli elementi dello schermo e altri dettagli di implementazione. Dico questo in parte per rendere le specifiche più leggibile, ma anche di separare l'espressione di prova, rispetto alle sottostanti dettagli implementativi. Si vuole fare questo in modo che i test in grado di ospitare più facilmente modifiche strutturali alle pagine web. Se you8217ve mai lavorato su test automatizzati su larga scala contro un browser web, si ha realmente bisogno di essere consapevoli del fatto che questi tipi di test possono essere molto fragili di fronte ai cambiamenti di interfaccia utente. Storyteller fornisce un sacco di strumentazione supplementare e registrazione delle prestazioni che può essere molto utile per il debug del test o di prestazioni Odio buttare questo là fuori, ma la capacità Storyteller8217s configurabile di tentativi in continua integrazione è molto utile per suite di test con una gran quantità di comportamento asincrono come si corre spesso in essere con le applicazioni web moderne perché qualcuno chiederà, o un appassionato di F inevitabilmente gettare questo fuori là, sì, there8217s Canopy così che avvolge un bel DSL intorno Selenio e fornisce una certa stabilizzazione. I8217m non denigrare Canopy minimamente, ma tutto quello che ho detto su come utilizzare selenio grezzo vale anche per utilizzare Canopy da solo. Per essere un po 'più occhio-angusto a questo proposito, una delle prime storie di successo di Storyteller 3 ha partecipato sostituzione di una suite di test male instabile che ha usato Canopy ingenuamente. Storyteller è un progetto a lungo in esecuzione per la creazione leggibili, specifiche eseguibili umani per i progetti. La nuova versione 4.0 è pensato per rendere Storyteller più facile da usare e consumare per le persone non tecnici e per migliorare la capacità developer8217s di risolvere gli errori di specifica. Dopo circa 5 mesi di sforzi, sono stato finalmente in grado di tagliare i Nugets 4,0 per Storyteller questa mattina e le più recenti aggiornamenti della documentazione. Se you8217re completamente nuovo per Storyteller, controllare la nostra pagina introduttiva o questo webcast. Se you8217re provenienti da Storyteller 3.0, è sufficiente sapere che sarà necessario prima convertire le vostre specifiche per il nuovo formato 4.0. Il Narratore Fixture API non ha avuto cambiamenti di rottura, ma i passi bootstrap sono un po 'diverso per accogliere il CLI dotnet. È possibile vedere l'intero elenco delle modifiche qui. o le grandi punti salienti di questa versione sono: CoreCLR Supporto Storyteller 4.0 può essere utilizzato su entrambi i 4.6 progetti o progetti che hanno come target la CoreCLR. A partire da ora, Storyteller è ora uno strumento cross-platform. Si può leggere di più sulle mie esperienze migrazione Cantastorie al CoreCLR qui. Abbraccia il CLI dotnet. Mi piace il nuovo cli dotnet e desiderio we8217d avuta anni fa. C'è un nuovo pacchetto di estensibilità 8220dotnet storyteller8221 CLI che prende il posto del vecchio strumento console ST. exe in 3.0 che dovrebbe essere più facile da configurare per i nuovi utenti. Markdown Ovunque Storyteller 4.0 ha cambiato il formato specifica per un Markdown più formato. ha aggiunto una nuova funzionalità per progettare e generare Fixture8217s con Markdown. e si può tranquillamente utilizzare il testo come Markdown in prosa entro le specifiche per migliorare la vostra capacità di comunicare le intenzioni nelle specifiche narratore. Modalità Stepthrough. test di integrazione può essere molto difficile da eseguire il debug quando falliscono. To ease the load, Storyteller 4.0 adds the new Stepthrough mode that allows you manually walk through all the steps of a Storyteller specification so you can examine the current state of the system under test as an aid in troubleshooting. Asynchronous Grammars . It8217s increasingly an async-first kind of world, so Storyteller follows suit to make it easier for you to test asynchronous code . Performance Assertions . Storyteller already tracks some performance data about your system as specifications run, so why not extend that to applying assertions about expected performance that can fail specifications on your continuous integration builds Other Things Coming Soon(ish) A helper library for using Storyteller with ASP Core applications with some help from Alba. I8217m hoping to recreate some of the type of diagnostics integration we have today with Storyteller and our FubuMVC applications at work for our newer ASP Core projects. A separate package of Selenium helpers for Storyteller An extension specifically for testing relational database code A 4.1 release with the features I didn8217t get around to in 4.0) How is Storyteller Different than Gherkin Tools First off, can we just pretend for a minute that GherkinCucumber tools like SpecFlow may not be the absolute last word for automating human readable, executable specifications By this point, I think most folks associate any kind of acceptance test driven development or truly business facing Behavioral Driven Development with the Gherkin approach 8212 and it8217s been undeniably successful. Storyteller on the other hand, was much more influenced by Fitnesse and could accurately be described as a much improved evolution of the old FIT model . SpecFlow is the obvious comparison for Storyteller and by far the most commonly used tool in the space. The bottom line for me with Storyteller vs. SpecFlow is that I think that Storyteller is far more robust technically in how you can approach the automated testing aspect of the workflow. SpecFlow might do the businesstesting to development workflow a little better (but I8217d dispute that one too with the release of Storyteller 4.0), but Storyteller has much, much more functionality for instrumenting, troubleshooting, and enforcing performance requirements of your specifications. I strongly believe that Storyteller allows you to tackle much more complex automated testing scenarios than other options. Here is a more detailed list about how Storyteller differs from SpecFlow: Storyteller is FOSS. So on one hand, you don8217t have to purchase any kind of license to use it, but you8217ll be dependent upon the Storyteller community for support. Instead of parsing human written text and trying to correlate that to the right calls in the code, Storyteller specifications are mostly captured as the input and expected output. Storyteller specifications are then 8220projected8221 into human readable HTML displays. Storyteller is much more table centric than Gherkin with quite a bit of functionality for set-based assertions and test data input. Storyteller has a much more formal mechanism for governing the lifecycle of your system under test with the specification harness rather than depending on an application being available through other means. I believe that this makes Storyteller much more effective at development time as you cycle through code changes when you work through specifications. Storyteller does not enforce the 8220GivenWhenThen8221 verbiage in your specifications and you have much more freedom to construct the specification language to your preferences. Storyteller has a user interface for editing specifications and executing specifications interactively (all React. js based now). The 4.0 version makes it much easier to edit the specification files directly, but the tool is still helpful for execution and troubleshooting. We do not yet have direct Visual Studio integration like SpecFlow (and I8217m somewhat happy to let them have that one)), but we will develop a dotnet test adapter for Storyteller when the dust settles on the VS2017csproj churn. Storyteller has a lot of functionality for instrumenting your specifications that8217s been indispensable for troubleshooting specification failures and even performance problems. The built in performance tracking has consistently been one of our most popular features since it was introduced in 3.0. When I was at Codemash this year, Matthew Groves was kind enough to let me do a podcast with him on Marten for the Cross Cutting Concerns podcast. Check it out . I8217m flying out to our main office next week and one of the big things on my agenda is talking over our practices around databases in our software projects. This blog post is just me getting my thoughts and talking points together beforehand. There are two general themes here, how I8217d do things in a perfect world and how to make things better within the constraints of the organization and software architecture that have now. I8217ve been a big proponent of Agile development processes and practices going back to the early days of Extreme Programming (before Scrum came along and ruined everything about the way that Scrappy ruined Scooby Doo cartoons for me as a child). If I8217m working in an Agile way, I want: Strong project and testing automation as feedback cycles that run against all changes to the system Some kind of easy traceability from a built or deployed system to exactly the version of the code and its dependencies. preferably automated through your source control processes Technologies, tools, and frameworks that provide high reversibility to ease the cost of doing evolutionary software design. From the get go, relational databases have been one of the biggest challenges in the usage of Agile software practices. They8217re laborious to use in automated testing, often expensive in time or money to install or deploy, the change management is a bit harder because you can8217t just replace the existing database objects the way we can with other code, and I absolutely think it8217s reduces reversibility in your system architecture compared to other options. That being said, there are some practices and processes I think you should adopt so that your Agile development process doesn8217t crash and burn when a relational database is involved. Keep Business Logic out of the Database, Period. I8217m strongly against having any business logic tightly coupled to the underlying database. but not everyone feels the same way. For one reason, stored procedure languages (tSQL, PLSQL, etc.) are very limited in their constructs and tooling compared to the languages we use in our application code (basically anything else). Mostly though, I avoid coupling business logic to the database because having to test through the database is almost inevitably more expensive both in developer effort and test run times than it would be otherwise. Some folks will suggest that you might want to change out your database later, but to be honest, the only time I8217ve ever done that in real life is when we moved from RavenDb to Marten where it had little impact on the existing structure of the code. In practice this means that I try to: Eschew usage of stored procedures. Yes, I think there are still some valid reasons to use sprocs, but I think that they are a 8220guilty until proven innocent8221 choice in almost any scenario Pull business logic away from the database persistence altogether whenever possible. I think I8217ll be going back over some of my old designing for testability blog posts from the CodebetterALT days to try to explain to our teams that 8220wrap the database in an interface and mock it8221 isn8217t always the best solution in every case for testability Favor persistence tools that invert the control between the business logic and the database over tooling like Active Record that creates a tight coupling to the database. What this means is that instead of having business logic code directly reading and writing to the database, something else (Dapper if we can, EF if we absolutely have to) is responsible for loading and persisting application state back and forth between the domain in code and the underlying database. The point is to be able to completely test your business logic in complete isolation from the database. I would make exceptions for use cases where using the database engine to do set based logic in a stored procedure is a more efficient way to solve the problem, but I haven8217t been involved in systems like that for a long time. Database per DeveloperTesterEnvironment My very strong preference and recommendation is to have each developer, tester, and automated testing environment using a completely separate database. The key reason is to isolate each thread of team activity to avoid simultaneous operations or database changes from interfering with each other. Sharing the database makes automated testing much less effective because you often get false negatives or false positives from database activity going on somewhere else at the same time 8212 and yes, this really does happen and I8217ve got the scars to prove it. Additionally, it8217s really important for automated testing to be able to tightly control the inputs to a test. While there are some techniques you can use to do this in a shared database (multi-tenancy usage, randomized data), it8217s far easier mechanically to just have an isolated database that you can easily control. Lastly, I really like being able to look through the state of the database after a failed test. That8217s certainly possible with a shared database, but it8217s much easier in my opinion to look through an isolated database where it8217s much more obvious how your code and tests changed the database state. I should say that I8217m concerned here with logical separation between different threads of activity. If you do that with truly separate databases or separate schemas in the same database, it serves the same goal. 8220The8221 Database vs. Application Persistence There are two basic development paradigms to how we think about databases as part of a software system: The database is the system and any other code is just a conduit to get data back and forth from the database and its consumers The database is merely the state persistence subsystem of the application I strongly prefer and recommend the 2nd way of looking at that, and act accordingly. That8217s a admittedly a major shift in thinking from traditional software development or database centric teams. In practice, this generally means that I very strongly favor the concept of an application database that is only accessed by one application and can be considered to be just part of the application. In this case, I would opt to have all of the database DDL scripts and migrations in the source control repository for the application. This has a lot of benefits for development teams: It makes it dirt simple to correlate the database schema changes to the rest of the application code because they8217re all versioned together Automated testing is easier within continuous integration builds becomes easier because you know exactly what scripts to apply to the database before running the tests No need for elaborate cascading builds in your continuous integration setup because it8217s just all together In contrast, a shared database that8217s accessed by multiple applications is a lot more potential friction. The version tracking between the two moving parts is harder to understand and it harms your ability to do effective automated testing. Moreover, it8217s wretchedly nasty to allow lots of different applications to float on top of the same database in what I call the 8220pond scum anti-pattern8221 because it inevitably causes nasty coupling issues that will almost result in regression bugs due to it being so much harder to understand how changes in the database will ripple out to the applications sharing the database. A much, much younger version of myself walked into a meeting and asked our 8220operational data store8221 folks to add a column to a single view and got screamed at for 30 minutes straight on why that was going to be impossible and do you know how much work it8217s going to be to test everything that uses that view young man Assuming that you absolutely have to continue to use a shared database like my shop does, I8217d at least try to ameliorate that by: Make damn sure that all changes to that shared database schema are captured in source control somewhere so that you have a chance at effective change tracking Having a continuous integration build for the shared database that runs some level of regression tests and then subsequently cascades to all of the applications that touch that database being automatically updated and tested against the latest version of the shared database. I8217m expecting some screaming when I recommend that in the office next week-) At the least, have some mechanism for standing up a local copy of the up to date database schema with any necessary baseline data on demand for isolated testing Some way to know when I8217m running or testing the dependent applications exactly what version of the database schema repository I8217m currently using. Git submodules Distribute the DB via Nuget Finally do something useful with Docker, distribute the DB as a versioned Docker image, and brag about that to any developer we meet The key here is that I want automated builds constantly running as feedback mechanisms to know when and what database changes potentially break (or fix too) one of our applications. Because of some bad experiences in the past, I8217m hesitant to use cascading builds between separate repositories, but it8217s definitely warranted in this case until we can get the big central database split up. At the end of the day, I still think that the shared database architecture is a huge anti-pattern that most shops should try to avoid and I8217d certainly like to see us start moving away from that model more and more. Document Databases over Relational Databases I8217ve definitely put my money where my mouth is on this (RavenDb early on, and now Marten ). In my mind, evolutionary or incremental software design is much easier with document databases for a couple reasons: Far fewer changes in the application code result in database schema changes It8217s much less work to keep the application and database in sync because the storage just reflects the application model Less work in the application code to transform the database storage to structures that are more appropriate for the business logic. Cioè relational databases really aren8217t great when your domain model is logically hierarchical rather than flat It8217s a lot less work to tear down and set up known test input states in document databases. With a relational database you frequently end up having to deal with extraneous data you don8217t really care about just to satisfy relational integrity concerns. Likewise, tearing down relational database state takes more care and thought than it does with a document database. I would still opt to use a relational database for reporting or if there8217s a lot of set based logic in your application. For simpler CRUD applications, I think you8217re fine with just about any model and I don8217t object to relational databases in those cases either. It sounds trivial, but it does help tremendously if your relational database tables are configured to use cascading deletes when you8217re trying to set a database into a known state for tests. Team Organization My strong preference is to have a completely self-contained team that has the ability and authority to make any and all changes to their application database, and that8217s most definitely been valid in my experience. Have the database managed and owned separately from the development team is a frequent source of friction and definitely a major hit to your reversibility that forces you to do more potentially wrong, upfront design work. It8217s much worse when that separate team does not share your priorities or simply works on a very different release schedule. I think it8217s far better for a team to own their database 8212 or at the very worst, have someone who is allowed to touch the database in the team room and team standup8217s. If I had full control over an organization, I would not have a separate database team. Keeping developers and database folks on separate team makes your team have to spend more time on inter-team coordination, takes away from the team8217s flexibility in deciding what they can deliver, and almost inevitably causes a bottleneck constraint for projects. Even worse in my mind is when neither the developers nor the database team really understand how their work impacts the other team. Even if we say that we have a matrix organization. I want the project teams to have primacy over functional teams. To go farther, I8217d opt to make functional teams (developers, testers, DBA8217s) be virtual teams solely for the purpose of skill acquisition, knowledge sharing, and career growth. My early work experience was being an engineer within large petrochemical project teams, and the project team dominant matrix organization worked a helluva lot better than it did at my next job in enterprise IT that focused more on functional teams. As an architect now rather than a front line programmer, I constantly worry about not being able to feel the 8220pain8221 that my decisions and shared libraries cause developers because that pain is an important feedback mechanism to improve the usability of our shared infrastructure or application architecture. Likewise, I worry that having a separate database team creates a situation where they8217re not very aware of the impact of their decisions on developers or vice versa. One of the very important lessons I was taught as an engineer was that it was very important to understand how other engineering disciplines work and what they needed so that we could work better with them. Now though, I do work in a shop that has historically centralized the control of the database in a centralized database team. To mitigate the problems that naturally arise from this organizational model, we8217re trying to have much more bilateral conversations with that team. If we can get away with this, I8217d really like to see members of that team spend more time in the project team rooms. I8217d also love it if we could steal a page from my original engineering job (Bechtel ) and suggest some temporary rotations between the database and developer teams to better appreciate how the other half of that relationship works and what their needs are. I just uploaded Marten 1.3.0 to Nuget (but note that Nuget has had issues today with the index updating being delayed). This release is mostly bugfixes, but there8217s some new functionality, and significant improvements to performance on document updates and bulk inserts. You can see the entire list of changes here with some highlights below. Thanks to Phillip Haydon There8217s a slew of new documentation on our website about Postgresql for Sql Server folks . What8217s New It wasn8217t a huge release for new features, but these were added: What8217s Next The next release is going to be Marten 2.0 because we need to make a handful of breaking API changes (don8217t worry, it8217s very unlikely that most users would hit this). The big ticket item is a lot more work to reduce memory allocations throughout Marten. The other, not-in-the-slightest-bit-sexy change is to standardize and streamline Marten8217s facilities for database change tracking with the hope that this work will make it far easier to start adding new features again. Years ago when I was in college and staying at my grandparent8217s farm, my uncle rousted me up well after midnight because he could see headlights in our pasture. We went to check it out to make sure no one was trying to steal cattle (it8217s very rare, but does happen) and found one of my grandparent8217s neighbors completely stuck in a fence row and drunkenly trying to get himself out. I don8217t remember the exact 8220conversation,8221 but his vocabulary was pretty well a single four letter expletive used as noun, verb, adjective, and adverb and the encounter went pretty quickly from potentially scary to comical. Likewise, when OSS maintainers deploy the phrase 8220I take pull requests,8221 they mean a slew of very different things depending on the scenario or other party. In order of positive to negative, here are the real meanings behind that phrase if you hear it from me: I think that would be a useful idea to implement and perfectly suitable for a newcomer to the codebase. Fallo. I like that idea, but I don8217t have the bandwidth to do that right now, would you be willing to take that on I don8217t think that idea is valuable and I wouldn8217t do it if it were just me, but if you don8217t mind doing that, I8217ll take it in. You8217re being way too demanding, and I8217m losing my patience with you. Since you8217re clearly a jerk, I8217m expecting this to make you go away if you have to do anything for yourself. My shop has started to slowly transition from FubuMVC to ASP Core (w and wo MVC) in our web applications. Instead of going full blown Don Quixote and writing my own alternative web framework like I did in 2009, I8217m trying to embrace the mainstream concentrate on tactical additions where I think that makes sense. I8217ve been playing around with a small new project called Alba that seeks to make it easier to write integration tests against HTTP endpoints in ASP Core applications by adapting the 8220Scenario8221 testing mechanism from FubuMVC. I8217ve pushed up an alpha Nuget (1.0.0-alpha-28) if you8217d like to kick the tires on it. Right now it8217s very early, but we8217re going to try to use it at work for a small trial ASP Core project that just started. I8217m also curious to see if anybody is interested in possibly helping out with either coding or just flat out testing it against your own application. A Quick Example First, let8217s say we have a minimal MVC controller like this one: With that in place, I can use Alba to write a test that exercises that HTTP endpoint from end to end like this: A couple points to note here: The easiest way to tell Alba how to bootstrap your ASP application is to just pass your Startup type of your application to the SystemUnderTest. ForStartupltTgt() method shown above in the constructor function of that test fixture class. Alba is smart enough to set up the hosting content path to the base directory of your application project. To make that concrete, say your application is at 8220srcMyApp8221 and you have a testing project called 8220srcMyApp. Testing8221 and you use the standard idiom using the same name for both the directory and the assembly name. In this case, Alba is able to interrogate your MyApp. Startup type, deduce that the 8220parallel8221 folder should be 8220MyApp. Testing,8221 and automatically set the hosting content path to 8220srcMyApp8221 if that folder exists. This can of course be overridden. When the Scenario() method is called, it internally builds up a new HttpContext to represent the request, calls the lambda passed into Scenario() to configure that HttpContext object and register any declarative assertions against the expected response, and executes the request using the raw 8220RequestDelegate8221 of your ASP Core application. There is no need to be running Kestrel or any other HTTP server to use Alba 8212 but it doesn8217t hurt anything if Kestrel is running in side of your application. The Scenario() method returns a small object that exposes the HttpContext of the request and a helper object to more easily interrogate the http response body for possible further assertions. Where would this fit in Alba itself isn8217t a test runner, just a library that can be used within a testing harness like xUnit or Storyteller to drive an ASP Core application. One of the things I8217m trying to accomplish this quarter at work is to try to come up with some suggestions for how developers should decide which testing approach to take in common scenarios. Right now I8217m worried that our automated testing frequently veers off into these two non-ideal extremes: Excessive mocking in unit tests where the test does very little to ascertain whether or not the code in question would actually work in the real system End to end tests using Selenium or Project White to drive business and persistence logic by manipulating the actual web application interface. These tests tend to be much more cumbersome to write and laborious to maintain as the user interface changes (especially when the developers don8217t run the tests locally before committing code changes). Alba is meant to live in the middle ground between these two extremes and give our teams an effective way to test directly against HTTP endpoints. These Scenario() tests originally came about in FubuMVC because of how aggressive we were being in moving cross cutting concerns like validation and transaction management to fubu8217s equivalent to middleware. Unit testing an HTTP endpoint action was very simple, but you really needed to exercise the entire Russian Doll of attached middleware to adequately test any given endpoint. How is this different than Microsoft. AspNetCore. TestHost While I8217ve been very critical of Microsoft8217s lack of attention to testability in some their development tools, let me give the ASP team some credit here for their TestHost library that comes out of the box. Some of you are going to be perfectly content with TestHost, but Alba already comes with much more functionality for common set up and verifications against HTTP requests. I think Alba can provide a great deal of value to the ecosystem even with an existing solution from Microsoft. I did use a bit of code that I borrowed from an ASPNet repository that was in turn copypasted from the TestHost repository. It8217s quite possible that Alba ends up using TestHost underneath the covers. TLDR 8211 I8217m getting burned out supporting StructureMap, but it8217s still very heavily used and I8217m really hoping to recruit some new blood to eventually take the project over from me. I8217ve been mulling over whether or not I want to continue development of StructureMap. At this point, I feel like the 3.0 and 4.0 releases dealt with all the major structural and performance problems that I could think of. If you ask me what I8217d like to be do to improve one of my other OSS projects I could bend your ear for hours, but with StructureMap I8217ve got nothing in mind. The project is still very widely used (1.5M downloads from Nuget) and I don8217t mean to just drop it by any means, but I8217m wondering if anybody (hopefully plural) would like to take ownership over StructureMap and actually keep it advancing I feel like the code is pretty clean, the test coverage is solid, and there8217s even close to comprehensive documentation already published online. Why I8217ve lost enthusiasm: I8217ve worked on StructureMap since 2003 I8217m mentally exhausted trying to stay on top of the user questions and problems that come rolling in and I8217m starting to resent the obligation to try to help users unwind far out usages of the tool and dozens of disparate application frameworks. There8217s a consistent and vocal backlash against IoC containers in my Twitter feeds. To some degree, I think their experiences are just very different than my own and I don8217t recognize the problems they describe in my own usage, but it still dampens enthusiasm. I8217ve got several other projects going that I8217m frankly more passionate about right now (Marten. Storyteller. a couple others) Microsoft has a small, built in IoC container as part of ASP Core that I suspect will eventually wipe out all the myriad OSS IoC containers. I can point to plenty advantages of StructureMap over what8217s built in, but most users probably wouldn8217t really notice At this point, with every application framework or service bus, folks are putting their IoC container behind an abstraction of some kind that tends to reduce StructureMap and other tools into the least common denominator functionality, so what8217s the point of trying to do anything new if it8217s gonna be thrown away behind a lame wrapping abstraction The ASP Core compatibility has been a massive headache for me with StructureMap and I8217m dreading the kinds of support questions that I expect to roll in from users developing with ASP Core. More on this one later. EDIT 15: We8217re still hiring for Salt Lake City or Phoenix. I can probably sell a strong remote candidate in the U. S. but I can8217t get away with remote folks in Europe (sorry). We8217re (Extend Health. part of Willis Towers Watson ) doing a little bit of reorganization with our software architecture team and how it fits within the company. As part of that, we8217re looking to grow the team with open slots in our main Salt Lake City office and our new Phoenix office. We might be able to add more remote folks later (I8217m in Austin, and another member is in Las Vegas), but right now we8217re looking for someone to be local. Who we8217re looking for Let me say upfront that I have a very conflicted relationship with the term 8220software architect.8221 I8217ve been a member of the dreaded, centralized architect team where we mostly just got in the way and I8217ve had to work around plenty of architecture team8217s 8220advice.8221 This time around, I want our new architecture team to be consistently considered to be an asset to our development teams while taking care of the strategic technical goals within our enterprise architecture. More than anything, the architecture team needs to be the kind of folks that our development teams want to work with and can depend on for useful advice and help. We8217re not going to be landing huge upfront specifications and there won8217t be much UML-spewing going on. You will definitely be hands on inside the code and it8217s likely you8217ll get to work on OSS projects as part of your role (check out my GitHub profile to get an idea of the kinds of work we8217ve done over the years). You8217re going to need to have deep software development experience and been in roles of responsibility on software teams before. You8217re going to need to have strong communication skills because one of your primary duties is to help and mentor other developers. A good candidate should be thoughtful, always on the lookout for better approaches or technologies, and able to take on all new technical challenges. It8217s not absolutely required, but a healthy GitHub or other OSS profile would be a big plus. The point there is just to look for folks that actually enjoy software development. You8217ll notice that I8217m not writing up a huge bullet list of required technical acronyms. I8217m more worried about the breadth and depth of your experience than an exact fit with whatever tools we happen to be using at the moment. That being said, we8217re mostly using on the server side (but with a heavy bias toward OSS tools) and various Javascript tools in the clients with a strong preference for React. jsRedux in newer development. We do a lot of web development, quite a bit of distributed messaging work, and some desktop tools used internally. Along the way you8217ll see systems that use document databases, event sourcing, CQRS, and reactive programming. I can safely promise you that our development challenges are considerably more interesting than the average shop. Messaggio di navigazione
Comments
Post a Comment