Correggi i bug o aspetti che il cliente li trovi?


35

Altre persone correggono i bug quando li vedono o aspettano che si verifichino arresti anomali / perdita di dati / persone che muoiono prima di risolverli?

Esempio 1

 Customer customer = null;
 ...
 customer.Save();

Il codice è chiaramente sbagliato e non c'è modo di aggirarlo: sta chiamando un metodo su un riferimento null. Non si verifica un arresto anomalo perché Savenon accede ai dati di istanza; quindi è proprio come chiamare una funzione statica. Ma qualsiasi piccola modifica in qualsiasi luogo può causare improvvisamente un codice non funzionante che non si arresta in modo anomalo: avviare un arresto anomalo.

Ma non è nemmeno inconcepibile che la correzione del codice:

Customer customer = null;
...
customer = new Customer();
try
   ...
   customer.Save();
   ...
finally
   customer.Free();
end;

potrebbe introdurre un arresto anomalo; uno non scoperto attraverso test unitari con copertura completa e test utente manuale.

Esempio 2

float speed = 0.5 * ((G * mass1 * mass2) / R) * Pow(time, 2);

Le persone che conoscono la fisica riconosceranno che dovrebbe essere R 2 nel denominatore.

Il codice è sbagliato, è assolutamente sbagliato. E sopravvalutare la velocità farà sì che i razzi retro sparino troppo presto, uccidendo tutti gli occupanti del veicolo spaziale.

Ma è anche possibile che sopravvalutare la velocità stia mascherando un altro problema: gli airbag non possono schierarsi mentre la navetta si muove troppo velocemente. Se improvvisamente ripariamo il codice:

float speed = 0.5 * ((G * mass1 * mass2) / Pow(R, 2)) * Pow(time, 2);

Ora la velocità è precisa e improvvisamente gli airbag si stanno diffondendo quando non dovrebbero.

Esempio 3

Ecco un esempio che ho avuto di recente, verificando se una stringa contiene caratteri non validi:

if (StrPos(Address, "PO BOX") >= 0)
{
   //Do something
}

E se si scopre che c'è un bug nel Do somethingramo? Correzione del codice ovviamente errato:

if (StrPos("PO BOX", Address) >= 0)
{
   //Do something
}

Risolve il codice, ma introduce un bug.


Per come la vedo io ci sono due possibilità:

  • correggi il codice e ottieni la colpa per averlo infranto
  • attendi che il codice si blocchi e venga accusato di avere un bug

Che cosa si politicamente fai?


Esempio 4 - Bug del mondo reale di oggi

Sto costruendo un oggetto, ma sto chiamando il costruttore sbagliato:

Customer customer = new Customer();

Si scopre che il costruttore "senza parametri" è in realtà un costruttore con parametri da più indietro nella catena dell'ereditarietà:

public Customer(SomeObjectThatNobodyShouldBeUsingDirectly thingy = null)
public Customer(InjectedDependancy depends)

Chiamarlo è un errore, poiché ignora tutti i costruttori successivi.

Potrei cambiare il lignaggio dell'oggetto per non esporre un costruttore così pericoloso, ma ora devo cambiare il codice in:

Customer customer = new Customer(depends);

Ma non posso garantire che questo cambiamento non rompa nulla. Come il mio esempio 1 sopra, forse qualcuno, da qualche parte, in qualche modo, in alcune condizioni esoteriche, dipende dal fatto che sia costruito Customerper essere non valido e pieno di spazzatura.

Forse l' Customeroggetto, ora che è stato costruito correttamente , consentirà l'esecuzione di un codice che in precedenza non ha mai fatto, e ora posso ottenere un arresto anomalo.

Non posso scommettere sulla vita di tua moglie.

E posso provarlo da qui a martedì, non posso giurare sulla vita di tua figlia che non ho introdotto una regressione.

Devo:

  • Correggi il codice e ti incolpano di averlo infranto? o
  • Lasciare il bug e ottenere la colpa quando il cliente lo trova?

33
Se non sei disposto a cambiare qualcosa perché potrebbe rompere qualcosa e ti consideri non qualificato per guardare cosa potrebbe accadere in altre parti del codice, cosa ci fai qui? Sei paralizzato dalla tastiera perché la riga di codice che stai per scrivere potrebbe essere errata?
David Thornley,

3
sicuramente una domanda ben studiata
Muhammad Alkarouri,

2
"Do Something" è spesso una chiamata ad altre funzioni che hai scritto o funzioni da librerie, in entrambi i casi il codice avrebbe dovuto essere testato dall'unità. La stessa procedura è anche testata dall'unità, lasciando la possibilità che vengano introdotti nuovi bug quando ne risolvi uno molto basso ... Se costruissi un ponte, lo testerei prima su scala ridotta invece di lasciare morire le persone che camminano sul ponte . Se non stai eseguendo test unitari quando sei preoccupato per i bug, stai sbagliando. In ogni caso lo risolvi sei incolpato, quindi invece di ripararlo potresti prevenirlo e non essere affatto accusato.
Tamara Wijsman,

2
'[aspetta] che le persone muoiano prima di aggiustarlo'! Santa mucca, spero seriamente che ci sia una sola risposta a questa ...
Chris Knight,

3
Come commento specifico di una cosa che hai detto: non sai se da qualche altra parte nel codice, si basano sul comportamento esoterico: quindi? Se qualcuno sta abusando di una regola di scoping chiaramente errata come hack nel suo codice, allora il codice è SBAGLIATO. Una buona OOP avrebbe evitato quel bug, ma non risolverlo perché hanno usato una cattiva pratica sta aggravando il problema, lasciandolo aperto per ulteriori abusi e rendendo il sistema più instabile tutt'intorno. Correggi il bug, spero che il test rilevi eventuali problemi, correggi più bug se non lo fa. La stabilità a lungo termine del prodotto è una metrica vitale.
CodexArcanum,

Risposte:


34

Questo dipende selvaggiamente dalla situazione, dal bug, dal cliente e dall'azienda. C'è sempre un compromesso da considerare tra la correzione dell'implementazione e la potenziale introduzione di nuovi bug.

Se dovessi dare una linea guida generale per determinare cosa fare, penso che andrebbe qualcosa del genere:

  1. Registrare il difetto nel sistema di tracciamento scelto. Discutere con i dirigenti / colleghi, se necessario.
  2. Se si tratta di un difetto con conseguenze potenzialmente disastrose (ad es. Il tuo esempio n. 2), corri, grida, salta su e giù fino a quando qualcuno non si accorge dell'autorità e determina un piano d'azione appropriato che mitigherà i rischi associati alla correzione dei bug. Questo potrebbe riportare indietro la data di uscita, salvare vite umane, lavare le finestre, ecc.
  3. Se si tratta di un difetto irreversibile o esiste una soluzione alternativa, valutare se il rischio di risolverlo supera il vantaggio della correzione. In alcune situazioni sarà meglio aspettare che il cliente lo attiri, poiché sai che non stai impiegando tempo a sistemare / ripetere il test delle cose quando non è richiesto al 100%.

Intendiamoci, questo vale solo quando sei vicino a una versione. Se sei in modalità di sviluppo completo, registrerei il difetto in modo che possa essere rintracciato, risolto e chiamato fatto. Se è qualcosa che richiede più di mezz'ora, per esempio, per risolvere e verificare, andrei al responsabile del team / manager e vedrei se il difetto dovrebbe essere inserito o meno nel ciclo di rilascio corrente o programmato per un tempo successivo.


Verissimo. Ecco perché (alcune) aziende hanno manager tecnici, scansioni di bug e così via: dare la priorità alle cose. Non sto dicendo di non prendere l'iniziativa - per niente - ma devi usare il buon senso. Prendere l'iniziativa sbagliata al momento sbagliato si chiama "essere un cannone libero" e può uccidere un'azienda. Inoltre, l'importanza di un determinato bug varia da compagnia a compagnia. Per alcuni programmi, un refuso in una finestra di dialogo è un bug cosmetico a bassa priorità da correggere in una versione futura e in altri è un'emergenza di arresto della nave.
Bob Murphy,

6
+1 per registrare il difetto. Altri difetti possono avere la priorità ...
Scossa

35

I clienti troveranno SEMPRE dei bug . Non ci sono mai bug nascosti da parte dei clienti. Alla fine i bug che introduci torneranno sempre a te. Non risolverli è semplicemente una cattiva pratica professionale. I professionisti non lo fanno.

Quando i clienti trovano bug, la società sembra brutta, non un singolo sviluppatore. Questo è molto peggio per l'azienda, quindi è il caso di apportare il cambiamento. Se non sei davvero sicuro di apportare questa modifica nel timore di introdurre altri bug, parla con uno sviluppatore più anziano, responsabile tecnico del progetto o chiunque altro sia nella posizione di prendere una decisione su tale modifica e successivamente gestirne le conseguenze.


2
Questa è una triste verità. Abbiamo dovuto consegnare un progetto che abbiamo testato come un matto, e comunque il cliente è riuscito a bloccarlo entro 3 minuti.
Oliver Weiler,

4
Metodo @Helper: Forse se lo avessi testato come persone sane sarebbe stato meglio.
Vinko Vrsalovic,

Metodo @Helper: anche se, più seriamente, se fossero davvero tre minuti, sembra che i tester non sapessero quali fossero i casi d'uso reali previsti dal cliente.
Vinko Vrsalovic,

8
Metodo @Helper: coinvolgi il cliente nei test (assumendo customer == client). Gli sviluppatori che scrivono e testano il codice rappresentano un problema per gli sviluppatori che non usano il software allo stesso modo. Gli sviluppatori sono gentili. È il loro lavoro - la loro arte: i clienti ci battono sopra come una scimmia su un panio. Quando possibile, condividi lo sforzo di test condividi la responsabilità. Questo non si adatta ad ogni ambiente, ma lavorando con i clienti come una squadra, non i consulenti possono portare a un software migliore.
Brian Chandley,

Ehi, peggio? (riempimento)
Ciao71,

24

Risolvi il bug

Siamo professionisti qui. Se trovi un percorso non riuscito nel codice che causerà un arresto anomalo o un comportamento errato, devi correggerlo. A seconda delle procedure del team, è probabile che sia necessario presentare un difetto, magari scrivere un test di regressione e verificare la correzione al momento giusto del ciclo della nave. Se si tratta di un bug a bassa priorità, il controllo nella correzione vicino all'inizio di una pietra miliare è sempre un buon momento perché se causi una regressione non influenzerai il ciclo di rilascio della pietra miliare.

Non confonderlo con il refactoring o apportando miglioramenti delle prestazioni non correlati a un bug delle prestazioni.

Un sistema distribuito di controllo del codice sorgente in cui è possibile mantenere un repository separato di "piccole correzioni di errori" e quindi unirle facilmente all'inizio di una pietra miliare è di grande aiuto qui.


4
+1. Aggiustalo. Se la correzione rompe qualcos'altro, allora anche qualcos'altro è stato rotto - correggilo anche tu. Se il tuo test non rileva queste interruzioni, allora il tuo test viene interrotto - correggi anche quello. Non puoi lasciarti spaventare cambiando il codice dalla paura di rompere qualcosa - quella strada porta solo alla totale rovina.
Tom Anderson,

21

Cosa direbbe il cliente?

Ecco come immagino che questo accada:

Cliente: si blocca quando faccio x.

Programmatore: Oh sì! Ricordo di averlo visto un po 'di tempo fa. Ho pensato che non fosse ancora un grosso problema, quindi l'ho lasciato lì.

Cliente: [raggiunge per oggetto contundente]

Sì. Risolvi il bug. Salverai il cliente da un'esperienza aggravante e riuscirai a risolverlo prima che diventi un'emergenza.

E se ritieni che la tua correzione potrebbe effettivamente causare un arresto, non hai ancora trovato una correzione.


8

Tutti gli esempi che hai dato sembrano avere un filo conduttore. Sembra che tu voglia correggere un bug che non capisci completamente. Lo dico perché noti la possibilità di conseguenze non intenzionali su ognuno.

Direi che probabilmente è un grosso errore e dato che Ben Laurie scrive non corregge un bug che non capisci . In questo famoso esempio il team Debian ha rotto la crittografia per OpenSSL per Debian e derivati ​​come Ubuntu quando hanno seguito i risultati di uno strumento di analisi.

Se ritieni che ci sia un difetto guardando il codice, assicurati di poter riprodurre il difetto in un modo che il cliente possa vedere. Se non puoi, perché non spendere le tue risorse per sistemare qualcos'altro.


7

Inizia a tagliare il tuo debito tecnico il prima possibile .

I tuoi esempi sembrano decisamente codice legacy , con molti debiti tecnici e ho la sensazione che ci sia la paura del cambiamento (A proposito, questa non è una critica o un giudizio). Tutto il tuo team deve riconoscere che hai questo debito tecnico (quindi non sei l'unico responsabile per esso) e quindi puoi decidere come affrontarlo.

Nell'esempio 1, se Save()non accede a nessun dato di istanza, quali dati del cliente salva esattamente? Inizia a risolvere e testarlo.

Nell'esempio 2, è facile coprire il calcolatore di velocità con i test e assicurarsi che calcoli il risultato corretto in tutti gli esempi chiave.

Nell'esempio 3, c'è il pericolo di riportare in vita il codice morto. Quel codice dovrebbe essere eliminato del tutto? Qual è l'intento della condizione booleana in questo caso se? È per garantire che la stringa non contenga caratteri non validi? O per assicurarsi che contenga "PO BOX"? Prima inizi a rispondere a tali domande, meglio è.

Dopo aver risolto alcuni di questi problemi, organizza una sorta di retrospettiva / post-mortem con il tuo team. È importante imparare dall'esperienza in modo da poter ridurre la velocità di iniezione del difetto in futuro.


5

Hai già buone risposte. Aggiungerò semplicemente qualcosa sulla questione della paura che qualcosa si blocchi.

Innanzitutto, nella situazione ideale il software è modulare, è progettato in modo corretto e vi è una buona separazione delle preoccupazioni. In questo caso, è improbabile che le modifiche apportate rompano qualsiasi cosa in quanto avrai il controllo di tutto il codice correlato e non ci sono sorprese nascoste.

Sfortunatamente, la situazione ideale è immaginaria. Indipendentemente dalla misura in cui l'accoppiamento è allentato, ci sarà l'accoppiamento e quindi la possibilità di rompere qualcos'altro.

La soluzione a questo è duplice:

  1. Rendi il codice il più strutturato possibile.
  2. Quando il codice è abbastanza isolato da sapere che non si romperà nient'altro, correggilo.

Rendere il codice ben strutturato non si ottiene riscrivendo l'intero codice in un nuovo progetto architettonico. Piuttosto, il refactoring guidato dai test è il tuo amico qui. In questo passaggio, non si modifica la funzionalità.

Il secondo passo è risolvere il bug.

Alcuni punti sono rilevanti:

  1. Il controllo della versione è assolutamente necessario per questo processo.
  2. La fase di refactoring e la fase di correzione dei bug sono meglio impegnate nel controllo della versione come commit separati, quindi ognuno ha una funzionalità storica ben definita.
  3. Non fissarti sulla possibilità di creare un altro bug, non otterrai nulla. Piuttosto, pensa a migliorare il tuo codice. In altre parole, a meno che tu non sappia che stai aumentando i bug anziché diminuirli, dovresti farlo.
  4. In relazione all'ultimo punto: non tentare di prevedere il futuro. Gli umani sono di parte a pensare di essere molto bravi nelle previsioni. In realtà i nostri poteri di previsione sono a breve termine. Quindi non preoccuparti di un vago bug futuro indefinito. Questo è anche il principio alla base di YAGNI .
  5. Lo strumento corrispondente al controllo delle versioni nel mondo dei bug è il bug tracker . Ne avrai bisogno anche tu.
  6. È necessario correggere i bug per due motivi: per soddisfare il cliente; e per poter progredire nel tuo sviluppo. Per usare l'esempio 3 (quello fisico): se il programma soddisfa il cliente con un'equazione così rotta, allora ci sono molte altre parti del software che sono state sviluppate erroneamente per mitigare questo errore (ad esempio la distribuzione dell'airbag). Se è richiesta una versione 2 (o 1.1) per questo software, sarà sempre più difficile sviluppare un codice corretto basato su questo difettoso. Stai quindi andando alla grande riscrittura o al grande fallimento. Entrambi dovresti evitare.

Questi sono già più di alcuni punti, quindi immagino che mi fermerò qui.


3

Devi prima considerare la definizione di un bug:

  1. Il codice letto non corrisponde a quello che ritieni giusto
  2. Il software non svolge correttamente i suoi compiti

Sembra che ti stai concentrando su # 1, dove # 2 è il posto migliore dove sederti. Certo, noi programmatori vogliamo che il nostro codice sia corretto (n. 1), ma le persone ci pagano perché funzioni (n. 2).

Ciò che è possibile o meno fare alla base di codice che potrebbe introdurre accidentalmente nuovi bug è irrilevante per la visione n. 2 del software attuale. Tuttavia, il numero 1 è importante per te stesso o per il programmatore di manutenzione che segue. A volte è difficile decidere, ma quando il conflitto n. 2 e n. 1 è necessario sapere che il n. 2 è chiaramente più importante.


2

Né. C'è un terzo modo: trovare un modo per dimostrare che "il codice problematico" sta effettivamente causando problemi dal punto di vista aziendale. Conferma ciò che trovi con BA / QA o almeno il tuo manager. Quindi pianificare la correzione quando tutti sono a conoscenza del problema.

Esistono più possibili scenari diversi da un bug valido nei casi menzionati:

  1. Il codice che stai guardando è un codice morto. Forse perché come ha detto Ysolik: i clienti trovano sempre bug. In caso contrario, forse il codice non verrà mai eseguito.
  2. C'era una situazione WTF in cui l'errore evidente aveva il suo scopo. (Stiamo parlando del codice di produzione, tutto potrebbe essere successo, giusto?)
  3. Business / clienti erano già a conoscenza del problema, ma non si sentono necessari per la correzione.
  4. Forse di più...

In ogni caso sopra, se sono un manager, non voglio che gli sviluppatori utilizzino il proprio giudizio e risolvano "l'errore". Riparare l'errore sul posto può aiutare nella maggior parte del tempo, ma quando va storto, può causare più problemi della sua buona intenzione.


1
Se vuoi solo assumere sviluppatori che non usano il proprio giudizio, ce ne sono molti davvero mediocri là fuori per te. Avrai difficoltà ad assumere quelli buoni, che hanno una certa fiducia nelle loro capacità.
David Thornley,

1
@ David: non estendere la mia opinione a un livello inappropriato. Gli sviluppatori hanno sicuramente bisogno del loro giudizio, ma dovrebbe esserci un limite. In questo caso, gli sviluppatori usano il loro giudizio per rilevare un potenziale bug e prendere ulteriori misure per risolverlo.
Codismo,

2

Faccio:

  • riparare il codice e incolpare per averlo rotto? o
  • lasciare il bug e ottenere la colpa quando il cliente lo trova?

Correggi il bug, avvia i test unitari e quando hanno successo, controlli la tua correzione.

(Oppure, se i test delle unità impiegano molto tempo, verifichi prima la correzione, quindi attendi se lo strumento CI ti invia una mail perché il commit ha interrotto qualcosa.)


1
O se usi un check-in con gate, configuralo in modo da non effettuare il check-in del codice non funzionante.
Adam Lear

3
Richiedere molto tempo non è una scusa per commettere un codice scadente.
Toby,

@Toby: chi parlava di scuse? Attualmente sto lavorando in un piccolo team, nemmeno una mezza dozzina di sviluppatori. I test unitari per il progetto durano 1 ora. La nostra politica è quella di eseguire i test che sembrano correlati a qualsiasi cosa tu faccia, quindi fare il check-in e far capire a CI se hai rotto qualcosa apparentemente non correlato. Questo non funzionerebbe in una grande squadra, ma in una piccola si risparmia molto tempo.
sbi,

1

Risolvili se si tratta di bug di crash / perdita di dati. Spedire un programma con un bug noto per la perdita di dati è decisamente dannoso e ingiustificabile.

Se il bug è estetico o non critico (può essere evitato), dovrebbe essere documentato e dovrebbe essere fornita una soluzione alternativa. Idealmente dovrebbe essere riparato, ma a volte è troppo costoso ripararlo per la versione corrente.

Notare come ogni progetto software più grande abbia una sezione "Problemi noti" nel file Leggimi che di solito elenca esattamente questo: bug conosciuti.

Conoscere i bug e NON comunicarli è accettabile solo per bug veramente minori / estetici.


1

Risolvilo e fallo testare. Se decidi di mantenere i bug conosciuti solo perché hai paura di trovare altri bug, il tuo programma diventa un campo minato di bombe a orologeria così in fretta che diventerà non riparabile prima di quanto pensi.

Dato che sei il padrone e il codice è il subordinato, potresti non aver paura di cambiarlo quando vedi che è sbagliato. La paura del codice ("potrebbe reagire rompendo altrove") è semplicemente inaccettabile.


0

Se c'è chiaramente un crasher o qualcosa di sbagliato , allora dovresti risolverlo. Se c'è un'ambiguità nelle specifiche, ovvero se ti trovi a pensare "bene il cliente potrebbe aspettarselo, ma allora sembra che potrebbe essere un bug" o un problema nelle specifiche, come "ci è stato chiesto di farlo ma fa schifo "allora devi scoprire cosa fare. Lanciare il codice oltre il muro e attendere il feedback dei clienti è un male: potresti chiedere a un product manager se ne hai uno o chiedere al cliente prima di distribuire il prodotto.

Ricorda, "sappiamo di quel problema e lo risolveremo in una versione futura" è sinonimo di "conosciamo quel problema, ma non ci preoccupiamo abbastanza di te da evitarti di affrontarlo".


0

La giusta linea d'azione non è né ignorare il bug, né "risolverlo" sul posto; proprio per i motivi che hai identificato nella tua domanda.

Penso che dovresti prima provare a capire il codice. Se il codice che stai vedendo ha una certa età e nessuno ha ancora notato il "bug", probabilmente c'è una ragione per questo. Prova a trovare questo motivo. Ecco cosa vorrei guardare prima di prendere una decisione:

  • Cronologia : utilizzare il software di controllo versione per rispondere alle domande: chi ha toccato il codice? Cosa sono cambiati? E con quali messaggi di commit l'hanno registrato? Puoi dedurre un motivo per cui il codice sembra simile?

  • Usa : quale codice utilizza il codice difettoso? E come? Il codice è morto? Esiste un altro codice che si basa sul comportamento difettoso?

  • Autore : se non riesci a raggiungere rapidamente una conclusione utilizzando le informazioni di cui sopra, chiedi all'autore del codice (almeno se ciò è possibile) perché il codice appare così. Di solito riceverai un "Oups, che dovrebbe essere risolto!" o un "No! Non cambiarlo !!! È necessario in quel modo!" subito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.