13 svar
266 visningar
TB16 behöver inte mer hjälp
TB16 182 – Fd. Medlem
Postad: 2 aug 2018 11:33

Är testfallen tillräckliga? (Junit)

Uppgift:

Nedanstående testsvit kontrollerar metoden checkArgument i klassen C. Vilket av

påståendena är sant?

public static boolean checkArgument(String arg) {

return arg.trim().length() > 0;

}

@Test

public void test1() {

assertTrue(C.checkArgument("abc"));

}

@Test

public void test2() {

assertTrue(C.checkArgument(" abc"));

}

@Test

public void test3() {

assertTrue(C.checkArgument("abc "));

}

@Test

public void test4() {

assertTrue(C.checkArgument(" abc "));

}

@Test

public void test5() {

assertFalse(C.checkArgument(""));

}

@Test

public void test6() {

assertFalse(C.checkArgument(" "));

 

a. Metoden klarar inte alla testen.

b. Det saknas ett viktigt testfall ovan.

c. Testfallen är tillräckliga

(Uppgiften är från en gammal tenta i objektorienterad programmering och eftersom svar saknas på denna uppgift så vänder jag mig till er i förhoppning att kanske få svar på mina tankar)

Min tankegång:

Så dessa tester kommer antingen att testa om returvärdet blir true (assertTrue) om sträng-argumentet är större än noll. Annars testas ifall metoden returnerar false (assertFalse). Metoden trim() används för att ta bort eventuella mellanrum (leading and trailing spaces) före och/eller innan själva ordet. Exempelvis om argumentet är “abc “ (längd 4) så kommer trim() ta bort mellanrummet efter 'c' så att vi får “abc” (längd 3).  
Jag ser inga felaktiga test och har kört alla tester (alla 6 tester är gröna).

Nu är frågan om det saknas ett viktigt testfall (b) eller om testfallen faktiskt är tillräckliga (c). Min första tanke är att det saknas ett test som testar ifall argumentet är null. Om strängen är null så kommer väl ett NullPointerException kastas, och därför så tycker jag påstående b låter mest rimligt? Frågan är om ett null-test räknas som ett viktigt testfall i detta sammanhang och om det saknas ytterligare testfall som bör läggas till? 

Lindehaven 820 – Lärare
Postad: 2 aug 2018 16:14

Du resonerar helt rätt - null-test är ett mycket viktigt testfall i detta och de flesta andra sammanhang. Du kan enkelt verifiera detta genom att lägga till ett sjunde testfall som testar null som argument.

TB16 182 – Fd. Medlem
Postad: 3 aug 2018 18:18
Lindehaven skrev:

Du resonerar helt rätt - null-test är ett mycket viktigt testfall i detta och de flesta andra sammanhang. Du kan enkelt verifiera detta genom att lägga till ett sjunde testfall som testar null som argument.

Okej, jag har lagt till ytterligare ett testfall (test7) nu, men när jag kör testet så får jag felmeddelandet "test failed". Gör jag något fel? (se nedan)

@Test
public void test7() {
String str = null;
assertNull(SomeClass.checkArgument(str));

AlvinB 4014
Postad: 3 aug 2018 18:29 Redigerad: 3 aug 2018 18:29

Problemet är att själva koden inte klarar ett null-test. Du måste ju lägga till en koll så att arg != null.

Själv tycker jag uppgiften är något oklar. Ett null-test saknas uppenbarligen, men det är ju inte bara ett test som ska läggas till, utan koden måste ju också ändras, och alltså är det ju inte bara ett testfall som saknas..

Lindehaven 820 – Lärare
Postad: 6 aug 2018 15:58

Håller med AlvinB. Prova att rätta koden med try och catch så att alla testfall går igenom. 

TB16 182 – Fd. Medlem
Postad: 9 aug 2018 12:37

Jag har provat att göra om metoden, men lyckas inte. Problemet är väl att den har returtyp boolean, och testet (assertNull) undersöker väl om returtypen är null? Bör man byta returtyp på metoden (checkArgument) från boolean till int där 3 siffror används för att motsvara antingen true, false eller null? 

AlvinB 4014
Postad: 9 aug 2018 12:47

Testet borde ju vara något sådant:

assertFalse(C.checkArgument(null));

Metoden bör ju kolla ifall argumentet är null och i så fall returnera false eftersom det inte är ett giltigt argument. Det är inte nödvändigt att ge någon mer information eftersom det inte spelar någon roll ifall det är en tom sträng eller null som gör att argumentet blir fel. Det viktiga är att man vet att argumentet inte funkar.

Dock kommer du märka att koden kommer att ge ifrån sig en NullPointerException ifall argumentet är null, vilket du måste åtgärda. Hur tror du att man gör det? (Try-catch är fel svar)

Lindehaven 820 – Lärare
Postad: 9 aug 2018 13:04

Håller med AlvinB - låt metoden returnera false om argumentet är null. Jag hävdar dock att try-catch är en av de kodkonstruktioner som enkelt kan lösa detta. Det finns fler lösningar (som vanligt är i programmering).

AlvinB 4014
Postad: 9 aug 2018 13:11

Fast där har du nog fel, tyvärr. NullPointerException är en RuntimeException, och sådana ska man inte använda try-catch för, dels för att exceptions är ganska ineffektiva, men framför allt för att det finns ett mycket enkelt sätt att förhindra dem.

En enkel if-sats med arg != null är allt man behöver för att förhindra en NullPointerException. Try-catch ska endast användas för att ta hand om oförutsedda exceptions.

TB16 182 – Fd. Medlem
Postad: 9 aug 2018 13:39

Nu gick null-testet igenom, men istället för att använda assertNull så använde jag assertFalse. Är det ok? (se uppdatering nedan)

checkArgument:

public static boolean checkArgument(String arg) {
if(arg != null) return arg.trim().length() > 0;
else return false;
}

...


null-testet:

...

test 7:
public void test7() {
assertFalse(C.checkArgument(null));
}

AlvinB 4014
Postad: 9 aug 2018 13:46

Just precis. Helt rätt. Nu har du ändrat koden så att det inte blir någon NullPointerException, och du har lagt till ett testfall som säkerställer att null-argument returnerar false.

Lindehaven 820 – Lärare
Postad: 9 aug 2018 13:46
AlvinB skrev:

Fast där har du nog fel, tyvärr. NullPointerException är en RuntimeException, och sådana ska man inte använda try-catch för, dels för att exceptions är ganska ineffektiva, men framför allt för att det finns ett mycket enkelt sätt att förhindra dem.

En enkel if-sats med arg != null är allt man behöver för att förhindra en NullPointerException. Try-catch ska endast användas för att ta hand om oförutsedda exceptions.

Jag menar att try-catch är ett sätt att lösa det på - inte fel men inte det bästa. En if-sats är bättre.

AlvinB 4014
Postad: 9 aug 2018 14:29
Lindehaven skrev:
AlvinB skrev:

Fast där har du nog fel, tyvärr. NullPointerException är en RuntimeException, och sådana ska man inte använda try-catch för, dels för att exceptions är ganska ineffektiva, men framför allt för att det finns ett mycket enkelt sätt att förhindra dem.

En enkel if-sats med arg != null är allt man behöver för att förhindra en NullPointerException. Try-catch ska endast användas för att ta hand om oförutsedda exceptions.

Jag menar att try-catch är ett sätt att lösa det på - inte fel men inte det bästa. En if-sats är bättre.

 Ja, det beror nog på vad man menar med fel... RuntimeExceptions finns bara för att visa att någonting har gått fel, de är inte till för att fångas upp av en try-catch-sats i en normal exekvering av kod.

Vore jag examinatör skulle jag ge fel för en sådan lösning, och jag tror de flesta erfarna Java-programmerare skulle vara benägna att hålla med.

TB16 182 – Fd. Medlem
Postad: 9 aug 2018 14:29

Stort tack för er hjälp. Jag är väldigt nöjd

Svara
Close