A próba-szerencse programozás a számítógép-programozás egy antimintája. Lényege, hogy a programozó apró változásokat visz véghez, remélve, hogy ezzel kijavít egy hibát. Közben rendszerint nem használja a verziókezelést, emiatt a megelőző változat elveszhet. Az apró változtatásokat, sorok megcserélésének eredményét teszteli is, bár ez a tesztelés nem kimerítő. Oka, hogy a programozó nem érti a hibát és a kódot.
Ezzel a módszerrel olyan új hibákat vezethetnek be, melyeket a teszteléssel nem vesznek észre, így legfeljebb csak akkor derülnek ki, amikor a programozó úgy ítéli, hogy sikerült kijavítania a hibát, és a projekt gépezete működésbe lendül.
A taktika nem produktív, ha:
- Nincsenek könnyen végrehajtható automatizált regressziós tesztek, amelyek lefedik a kódbázist.
- Nincs tesztvezérelt fejlesztés, így tapasztalati teszteléssel nehéz megállapítani, hogy a releváns esetek többségében működik-e.
- Nincs verziókezelés (GIT, Mercurial vagy SVN), nincs elmentett megelőző állapot, nincsenek közben mentések sem, így a legrosszabb esetben a régi állapot elvész, pedig lehet, hogy az lenne a legjobb. Sok hibás indítás és javítás történik, mielőtt eléri a megnyugtató végpontot.
Formális verifikáció hiányában a kód minősége nem biztosított.
Oka, hogy a programozó nem érti a hibát, nem érti, hogy miért csinálja a kód azt, amit. Ennek oka lehet az API nem megfelelő dokumentációja. Mások a referencia kódot másolják át, amiről azt hiszik, hogy korrekt, pedig lehet, hogy az is próba-szerencse módon készült.
Bizonyos esetekben a programozó tudja igazolni, hogy a többi lehetséges permutáció, változat közül az egyiknek működnie kell, akkor megtalálhatja azt a változatot, amiről utólag igazolhatja, hogy az a legjobb.
Példa
Az alábbi C példa célja, hogy megtalálja számjegyek egy sorozatát egy hosszabb stringben, és kimásolja őket; de több problémától is szenved:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
const char* buffer = "123abc";
char destination[10];
int i = 0;
int j = 0;
int l = strlen(buffer);
while (i < l) {
if (isdigit(buffer[i])) {
destination[j++] = buffer[i++];
}
++i;
}
destination[j] = '\0';
printf("%s\n", destination);
}
Először is, nem a jó választ adja. A kódban megadott stringet használva "13", míg a korrekt válasz "123". Aki nem veszi észre a szerkezeti problémát, az egy utasításra áll rá, mondva, hogy van egy extra növelés. Eltávolítja a "++i" sort, de a teszt végtelen ciklust eredményez. Visszateszi a ++i sort, majd eltávolítja az előzetes növelést a buffer[i++]-ből:
if (isdigit(buffer[i])) {
destination[j++] = buffer[i];
}
Ezután már megkapja a korrekt választ, és megkönnyebbülten befejezi a kódolást.
További tesztek különféle stringekkel azt mutatják, hogy a kód még nem jó:
- Ha a bemenetben több szám van, akkor a kimenetbe bekerül az összes számjegy, például "123ab456"-ból kapjuk, hogy "123456".
- Ha a bemenő string hosszabb, mint a buffer, akkor a buffer túlcsordul.
- Ha a bemenő string hosszabb, mint INT_MAX, akkor a viselkedés nem definiált. Ennek oka, hogy strlen() unsigned int számot ad vissza, ami így nagyobb lehet a maximális intnél.
- Ha a char előjeles, és a string olyan karaktereket tartalmaz, amelyek nincsenek a 0..UCHAR_MAX tartományban, az isdigit() viselkedése definiálatlan.
Míg a megoldás sok stringre működik, nem egészen korrekt, és mivel nem sikerült megérteni a kódot, a hibák felderítetlenek maradnak egészen egy későbbi tesztfázisig.[1]
Jegyzetek
Fordítás
Ez a szócikk részben vagy egészben a Programming by permutation című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.