NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Testovaní JUnit

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Qestin
Člen
Avatar
Qestin:28.2.2017 18:21

Dobrý den,

mohl by mi někdo poradit s testováním převodu římských číslic na arabské a naopak? Zdrojový kód programu je následující:

package Roman;

/**
 *
 * @author Martin Zeman
 */
public class Roman {

    static class Dvojice { //vnořená statická třída

        int arab;
        String roman;

        Dvojice(int arab, String roman) {
            this.arab = arab;
            this.roman = roman;
        }
    }

    static Dvojice tabulka[] = { //převodní tabulka = statické pole instanční třídy Dvojice
        new Dvojice(1000, "M"), //zeptám se je číslo větší než tiscí pokud ano přidám M a tisíc odeštu
        new Dvojice(900, "CM"), //ptám se znovu zda je číslo větší pokud ne skáču dál
        new Dvojice(500, "D"),
        new Dvojice(400, "CD"),
        new Dvojice(100, "C"),
        new Dvojice(90, "XC"),
        new Dvojice(50, "L"),
        new Dvojice(40, "XL"),
        new Dvojice(10, "X"),
        new Dvojice(9, "IX"),
        new Dvojice(5, "V"),
        new Dvojice(4, "IV"),
        new Dvojice(1, "I")
    };


    public static int fromRoman(String s) throws NumberFormatException {
        int vysl = 0;
        while (s.length() != 0) {
            for (Dvojice tabulka1 : tabulka) {
                while (s.startsWith(tabulka1.roman)) {
//                    if (){
//                        throw new NumberFormatException();
//                    }
vysl += tabulka1.arab;
s = s.substring(tabulka1.roman.length());
break;
                }
            }
            if (vysl>3999) throw new IllegalArgumentException("Moc velké číslo");
      }
return vysl;
    }

    /*
    String s=ss;
    if((s.length()==0)||!alfaOK(a)||!seqOK(s)){
        throws new NumberFormatException(ss);
    }
    int l;
    int vysl=0;
    while(s.length()!=0){
        l=s.length();
    for (int i = 0;i<tabulka.length;i++){
        if(s.startWith(tabulka[i].roman)){
            if(!checkNext(vysl, tabulka[i].arab)){
                throw new NumberFormatException(ss+ " " + s + " " + tabulka[i].arab + " " + vysl);
            }
            vysl += tabulka[i].arab;
            s=s.substring(tabulka[i].roman.length()};
            break;
        }
    }
    if (s.length()==1);
    throw new NumberFormatException(ss)
    }
    }
    return vysl;
    }
    */



    public static String toRoman(int i) throws IllegalArgumentException {
        if ((i > 3999) || (i <= 0)) {
            throw new IllegalArgumentException();
        } else {
            int cislo = i;
            String vysl = "";
            while (cislo > 0) {
                for (Dvojice tabulka1 : tabulka) {
                    if (cislo >= tabulka1.arab) {
                        vysl = vysl + tabulka1.roman;
                        cislo = cislo - tabulka1.arab;
                        break;
                    }
                }
            }
            return vysl;
        }
   /*    static Dvojice tabulka[] = {
      };  */
    }



    public static void main(String[] args) {
        System.out.println("3999 římsky = " + toRoman(3999));
        System.out.println("1005 římsky = " + toRoman(1005));
        System.out.println("MMMCMXCIX arabsky = " + fromRoman("MMMCMXCIX"));
        System.out.println("XXX arabsky = " + fromRoman("XXX"));
        /*      String r = "DLNVI";
        System.out.println(r + "--> " + fromRoman(r));
*/
    }


}

Potřeboval bych poradit s testováním, mělo by to obsahovat 8 testovacích metod, strukturu mám, ale nevím jak to dodělat? Viz. zdrojový kód:

package roman;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class RomanTest extends TestCase {
    class Dvojice {
        int arab;
        String roman;
Dvojice (int arab, String roman) {
this.arab=arab;
this.roman=roman;
}
};
Dvojice knownValues [] = {
new Dvojice(1,"I"),
new Dvojice(2,"II"),
new Dvojice(3,"III"),
new Dvojice(4,"IV"),
new Dvojice(5,"V"),
new Dvojice(6,"VI"),
new Dvojice(7,"VII"),
new Dvojice(8,"VIII"),
new Dvojice(9,"IX"),
new Dvojice(10,"X"),
new Dvojice(50,"L"),
new Dvojice(100,"C"),
new Dvojice(500,"D"),
new Dvojice(1000,"M"),
new Dvojice(31,"XXXI"),
new Dvojice(148,"CXLVIII"),
new Dvojice(294,"CCXCIV"),
new Dvojice(312,"CCCXII"),
new Dvojice(421,"CDXXI"),
new Dvojice(528,"DXXVIII"),
new Dvojice(621,"DCXXI"),
new Dvojice(782,"DCCLXXXII"),
new Dvojice(870,"DCCCLXX"),
new Dvojice(941,"CMXLI"),
new Dvojice(1043,"MXLIII"),
new Dvojice(1110,"MCX"),
new Dvojice(1226,"MCCXXVI"),
new Dvojice(1301,"MCCCI"),
new Dvojice(1485,"MCDLXXXV"),
new Dvojice(1509,"MDIX"),
new Dvojice(1607,"MDCVII"),
new Dvojice(2499,"MMCDXCIX"),
new Dvojice(2574,"MMDLXXIV"),
new Dvojice(2646,"MMDCXLVI"),
new Dvojice(2723,"MMDCCXXIII"),
new Dvojice(2892,"MMDCCCXCII"),
new Dvojice(2975,"MMCMLXXV"),
new Dvojice(3051,"MMMLI"),
new Dvojice(3313,"MMMCCCXIII"),
new Dvojice(3408,"MMMCDVIII"),
new Dvojice(3501,"MMMDI"),
new Dvojice(3610,"MMMDCX"),
new Dvojice(3743,"MMMDCCXLIII"),
new Dvojice(3844,"MMMDCCCXLIV"),
new Dvojice(3888,"MMMDCCCLXXXVIII"),
new Dvojice(3940,"MMMCMXL"),
new Dvojice(3999,"MMMCMXCIX"),
};
public RomanTest(String name) {
super(name);
}
    @Override
    protected void setUp () {
}
public void testToRomanKnownValues () {
        for (Dvojice knownValue : knownValues) {
            String vysl = Roman.toRoman(knownValue.arab);
            assertEquals(knownValue.roman, vysl);
        }
}
public void testFromRomanKnownValues () {
        for (Dvojice knownValue : knownValues) {
            int vysl = Roman.fromRoman(knownValue.roman);
            assertEquals(knownValue.arab, vysl);
        }
}
    @SuppressWarnings("empty-statement")
    public void testToRomanException () {
int badValues [] = { 0, -1, 4000 };
for (int i = 0; i < badValues.length; i++) {
try {
String vysl=Roman.toRoman(badValues[i]);
}
catch (IllegalArgumentException e) {
continue;
}
fail("Expected IllegalArgumentException");
};
}
    @SuppressWarnings("empty-statement")
    public void testIllegalCharacters () {
String badValues [] = { "I ", "i", "a", "mm", "d", "MCi" };
        for (String badValue : badValues) {
            try {
                int vysl = Roman.fromRoman(badValue);
            }catch (NumberFormatException e) {
                continue;
            }           fail("Expected IllegalArgumentException for " + badValue);
        }
;
}
    @SuppressWarnings("empty-statement")
    public void testTooManyRepeatedNumerals () {
String badValues [] = { "MMMM", "VV", "LL", "CCCC", "DD", "IIII" };
        for (String badValue : badValues) {
            try {
                int vysl = Roman.fromRoman(badValue);
            }catch (NumberFormatException e) {
                continue;
            }           fail("Expected IllegalArgumentException for " + badValue);
        }
;
}
    @SuppressWarnings("empty-statement")
    public void testRepeatedPairs () {
String badValues [] = { "CMCM", "CDCD", "IVIV", "IXIX", "XLXL" };
        for (String badValue : badValues) {
            try {
                int vysl = Roman.fromRoman(badValue);
            }catch (NumberFormatException e) {
                continue;
            }           fail("Expected IllegalArgumentException for " + badValue);
        }
;
}
    @SuppressWarnings("empty-statement")
    public void testMalformedAntecedent () {
String badValues [] = { "IIMMCC", "VX", "DCM", "CMM", "CMD", "IXIV", "MCMC",
"XCX", "IVI", "LM", "LD", "LC" };
int vysl;
        for (String badValue : badValues) {
            try {
                vysl = Roman.fromRoman(badValue);
            }catch (NumberFormatException e) {
                continue;
            }           fail("Expected IllegalArgumentException for " + badValue + " (" + vysl);
        }
;
}
    @SuppressWarnings("empty-statement")
    public void testSanity () {
for (int i=1; i < 4000; i++) {
int vysl = Roman.fromRoman(Roman.toRoman(i));
assertEquals(i, vysl);
};
}
public static void main (String[] args) {
junit.textui.TestRunner.run (suite());
}
public static Test suite() {
return new TestSuite(RomanTest.class);
}
};

Děkuji za všechny rady :-) A přeji hezký večer!

 
Odpovědět
28.2.2017 18:21
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 18:46

Ahoj, nechcí být nějak extra kritický, ale máš to téměř celé špatně. Bylo by dobré si nejdříve o JUnit testech něco přečíst. Dobrá rada: nikdy v testech nepoužívej vlastní cykly, podmínky, try/catch bloky. Prostě nic, co by mohlo ovlivňovat chování testu. Testy mají být krátké, ideálně na pár řádek max 5 (jasně, může být i víc, ale spíše méně). Nepoužívej starou JUnit knihovnu, pokud k tomu nemáš nějaký důvod. Pokud potřebuješ dodávat do testů hromadu stejných parametrů, je dobré to řešit parametrizovanými testy. Jeden takový jsem Ti napsal na tu první metodu. Kód je tady. Možná je to dlouhý kód, ale přesně testuje jednu věc. Takto můžeš převést všechny tvoje testovací metody.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
28.2.2017 18:46
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Qestin
Člen
Avatar
Odpovídá na Petr Štechmüller
Qestin:28.2.2017 19:19

Aha, děkuji. To testování jsme dostali od učitele, aby jsme si mohli vyzkoušet jak to funguje, ale právě vůbec to nefunguje, takže nechápu proč nám to dal. Tobě děkuji za radu a jdu na to kouknout. Zkusím udělat ty další, tak mi je prosím zkontroluj.

 
Nahoru Odpovědět
28.2.2017 19:19
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 19:21

Jasný, není problém. Stáhni si JUnit ve verzi 4, nebo 5. Trojka je dost stará a 5 zase moc nová. Ten příklad je pro verzi 4.

Nahoru Odpovědět
28.2.2017 19:21
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Qestin
Člen
Avatar
Odpovídá na Petr Štechmüller
Qestin:28.2.2017 19:25

Momentálně na to koukám a mám verzi 4.12 ? Je to možný ?

 
Nahoru Odpovědět
28.2.2017 19:25
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 19:26

Jo, to by měla být nejnovější verze čtyřky...

Nahoru Odpovědět
28.2.2017 19:26
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 19:28

Co jsem tady tak hledal, tak tu existuje jeden článek o JUnit testech, ale moc se mi nelíbí. Spíš tě doporučím sem. Zde můžeš čerpat informace.

Nahoru Odpovědět
28.2.2017 19:28
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Qestin
Člen
Avatar
Odpovídá na Petr Štechmüller
Qestin:28.2.2017 19:29

Ok, kouknu na to.

 
Nahoru Odpovědět
28.2.2017 19:29
Avatar
Qestin
Člen
Avatar
Odpovídá na Qestin
Qestin:28.2.2017 19:54
package Roman;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

import junit.framework.*;

public class RomanTest extends TestCase {

    class Dvojice {

        int arab;
        String roman;

        Dvojice(int arab, String roman) {
            this.arab = arab;
            this.roman = roman;
        }
    };
    Dvojice knownValues[] = {
        new Dvojice(1, "I"),
        new Dvojice(2, "II"),
        new Dvojice(3, "III"),
        new Dvojice(4, "IV"),
        new Dvojice(5, "V"),
        new Dvojice(6, "VI"),
        new Dvojice(7, "VII"),
        new Dvojice(8, "VIII"),
        new Dvojice(9, "IX"),
        new Dvojice(10, "X"),
        new Dvojice(50, "L"),
        new Dvojice(100, "C"),
        new Dvojice(500, "D"),
        new Dvojice(1000, "M"),
        new Dvojice(31, "XXXI"),
        new Dvojice(148, "CXLVIII"),
        new Dvojice(294, "CCXCIV"),
        new Dvojice(312, "CCCXII"),
        new Dvojice(421, "CDXXI"),
        new Dvojice(528, "DXXVIII"),
        new Dvojice(621, "DCXXI"),
        new Dvojice(782, "DCCLXXXII"),
        new Dvojice(870, "DCCCLXX"),
        new Dvojice(941, "CMXLI"),
        new Dvojice(1043, "MXLIII"),
        new Dvojice(1110, "MCX"),
        new Dvojice(1226, "MCCXXVI"),
        new Dvojice(1301, "MCCCI"),
        new Dvojice(1485, "MCDLXXXV"),
        new Dvojice(1509, "MDIX"),
        new Dvojice(1607, "MDCVII"),
        new Dvojice(2499, "MMCDXCIX"),
        new Dvojice(2574, "MMDLXXIV"),
        new Dvojice(2646, "MMDCXLVI"),
        new Dvojice(2723, "MMDCCXXIII"),
        new Dvojice(2892, "MMDCCCXCII"),
        new Dvojice(2975, "MMCMLXXV"),
        new Dvojice(3051, "MMMLI"),
        new Dvojice(3313, "MMMCCCXIII"),
        new Dvojice(3408, "MMMCDVIII"),
        new Dvojice(3501, "MMMDI"),
        new Dvojice(3610, "MMMDCX"),
        new Dvojice(3743, "MMMDCCXLIII"),
        new Dvojice(3844, "MMMDCCCXLIV"),
        new Dvojice(3888, "MMMDCCCLXXXVIII"),
        new Dvojice(3940, "MMMCMXL"),
        new Dvojice(3999, "MMMCMXCIX"),};

    public RomanTest(String name) {
        super(name);
    }

    protected void setUp() {
    }

    public void testToRomanKnownValues() {
        for (int i = 0; i < knownValues.length; i++) {
            String vysl = Roman.toRoman(knownValues[i].arab);
            assertEquals(knownValues[i].roman, vysl);
        }
    }

    public void testFromRomanKnownValues() {
        for (int i = 0; i < knownValues.length; i++) {
            int vysl = Roman.fromRoman(knownValues[i].roman);
            assertEquals(knownValues[i].arab, vysl);
        }
    }

    public void testToRomanException() {
        int badValues[] = {0, -1, 4000};
        for (int i = 0; i < badValues.length; i++) {
            try {
                String vysl = Roman.toRoman(badValues[i]);
            } catch (IllegalArgumentException e) {
                continue;
            }
            fail("Expected IllegalArgumentException");
        };
    }

    public void testIllegalCharacters() {
        String badValues[] = {"I ", "i", "a", "mm", "d", "MCi"};
        for (int i = 0; i < badValues.length; i++) {
            try {
                int vysl = Roman.fromRoman(badValues[i]);
            } catch (NumberFormatException e) {
                continue;
            }
            fail("Expected IllegalArgumentException for " + badValues[i]);
        };
    }

    public void testTooManyRepeatedNumerals() {
        String badValues[] = {"MMMM", "VV", "LL", "CCCC", "DD", "IIII"};
        for (int i = 0; i < badValues.length; i++) {
            try {
                int vysl = Roman.fromRoman(badValues[i]);
            } catch (NumberFormatException e) {
                continue;
            }
            fail("Expected IllegalArgumentException for " + badValues[i]);
        };
    }

    public void testRepeatedPairs() {
        String badValues[] = {"CMCM", "CDCD", "IVIV", "IXIX", "XLXL"};
        for (int i = 0; i < badValues.length; i++) {
            try {
                int vysl = Roman.fromRoman(badValues[i]);
            } catch (NumberFormatException e) {
                continue;
            }
            fail("Expected IllegalArgumentException for " + badValues[i]);
        };
    }

    public void testMalformedAntecedent() {
        String badValues[] = {"IIMMCC", "VX", "DCM", "CMM", "CMD", "IXIV", "MCMC",
            "XCX", "IVI", "LM", "LD", "LC"};
        int vysl;
        for (int i = 0; i < badValues.length; i++) {
            try {
                vysl = Roman.fromRoman(badValues[i]);
            } catch (NumberFormatException e) {
                continue;
            }
            fail("Expected IllegalArgumentException for " + badValues[i] + " (" + vysl);
        };
    }

    public void testSanity() {
        for (int i = 1; i < 4000; i++) {
            int vysl = Roman.fromRoman(Roman.toRoman(i));
            assertEquals(i, vysl);
        };
    }

    public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
    }

    public static TestSuite suite() {
        return new TestSuite(RomanTest.class);
    }
};

Trochu jsem to teď pozměnil a nevím, zda je to teď dobře, vypisuje mi to tohle:

run:
..F..F..F..F
Time: 0,03
There were 4 failures:

  1. testRepeatedPa­irs(Roman.Roman­Test)junit.fra­mework.Asserti­onFailedError: Expected IllegalArgumen­tException for CMCM

    at Roman.RomanTes­t.testRepeated­Pairs(RomanTes­t.java:139)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke0(Na­tive Method)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke(Na­tiveMethodAcces­sorImpl.java:62)

    at sun.reflect.De­legatingMetho­dAccessorImpl­.invoke(Delega­tingMethodAcces­sorImpl.java:43)

    at Roman.RomanTes­t.main(RomanTes­t.java:165)

  2. testIllegalCha­racters(Roman­.RomanTest)ju­nit.framework­.AssertionFai­ledError: Expected IllegalArgumen­tException for i

    at Roman.RomanTes­t.testIllegal­Characters(Ro­manTest.java:115)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke0(Na­tive Method)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke(Na­tiveMethodAcces­sorImpl.java:62)

    at sun.reflect.De­legatingMetho­dAccessorImpl­.invoke(Delega­tingMethodAcces­sorImpl.java:43)

    at Roman.RomanTes­t.main(RomanTes­t.java:165)

  3. testMalformedAn­tecedent(Roman­.RomanTest)ju­nit.framework­.AssertionFai­ledError: Expected IllegalArgumen­tException for IIMMCC (2198

    at Roman.RomanTes­t.testMalforme­dAntecedent(Ro­manTest.java:153)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke0(Na­tive Method)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke(Na­tiveMethodAcces­sorImpl.java:62)

    at sun.reflect.De­legatingMetho­dAccessorImpl­.invoke(Delega­tingMethodAcces­sorImpl.java:43)

    at Roman.RomanTes­t.main(RomanTes­t.java:165)

  4. testTooManyRe­peatedNumeral­s(Roman.Roman­Test)junit.fra­mework.Asserti­onFailedError: Expected IllegalArgumen­tException for MMMM

    at Roman.RomanTes­t.testTooMany­RepeatedNumeral­s(RomanTest.ja­va:127)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke0(Na­tive Method)

    at sun.reflect.Na­tiveMethodAcces­sorImpl.invoke(Na­tiveMethodAcces­sorImpl.java:62)

    at sun.reflect.De­legatingMetho­dAccessorImpl­.invoke(Delega­tingMethodAcces­sorImpl.java:43)

    at Roman.RomanTes­t.main(RomanTes­t.java:165)

FAILURES!!!
Tests run: 8, Failures: 4, Errors: 0

Jsem teď z toho celého zmatený, že vůbec nevím co mi to říká?

 
Nahoru Odpovědět
28.2.2017 19:54
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 20:00

Četl jsi vůbec ten můj kód? Pořád nechápu, proč děláš vlastní try/catch bloky. Ty by v testech vůbec neměly být

Nahoru Odpovědět
28.2.2017 20:00
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Qestin
Člen
Avatar
Odpovídá na Petr Štechmüller
Qestin:28.2.2017 20:05

Jojo, ale bohužel to dohromady nedám.

Editováno 28.2.2017 20:05
 
Nahoru Odpovědět
28.2.2017 20:05
Avatar
Odpovídá na Qestin
Petr Štechmüller:28.2.2017 20:06

Co konkrétně Ti nefunguje?

Nahoru Odpovědět
28.2.2017 20:06
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Qestin
Člen
Avatar
Odpovídá na Petr Štechmüller
Qestin:28.2.2017 20:08

Tady spíš o to, že se musím držet zadání a to tvoje je úplně jiný. Takže se snažím udělat to co mám.

 
Nahoru Odpovědět
28.2.2017 20:08
Avatar
Petr Pek
Člen
Avatar
Odpovídá na Petr Štechmüller
Petr Pek:2.3.2017 17:28

Zdravím,

zkoušel jsem si ten test, a aby fungoval, musel jsem si přidat anotaci:

@RunWith(value = Parameterized­.class)

použil jsem junit 4.12

 
Nahoru Odpovědět
2.3.2017 17:28
Avatar
Odpovídá na Petr Pek
Petr Štechmüller:2.3.2017 17:29

Jo jasný, to jsem asi nějak zapomněl přidat...
btw to value tam nemusí být. Stačí, když to bude takto:

@RunWith(Parameterized.class)
Editováno 2.3.2017 17:29
Nahoru Odpovědět
2.3.2017 17:29
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 15 zpráv z 15.