Disqus aplikaci se nepodařilo zobrazit. Jste-li administrátor, prosím shlédněte náš návod co dělat při těchto potížích.

Jan Novotný • před 11 let

Díky moc za článek - my takový validátor taky samozřejmě máme a tak jsem si zkusmo doplnil tebou popisované use-casy do našeho testu a voila - prošly všechny. Každopádně dík za nasdílení, protože 2x měř a jednou řež.

Sice se tu strhlo zbytečné lynčování ohledně formy těch testů, ale je lepší mít nějaké testy než testy žádné. 

Co se týká validace - vždycky je možné postupovat způsobem, že uživatele pustíme dál i když RČ neodpovídá (aby se pokryly zmíněné vyjímky), ale 99% uživatelů se spíš při psaní uklepne, než že by bylo tolik vyjímek. V takovém případě ho můžeme varovat, že se pravděpodobně zmýlil a jestli se nechce opravit.

Lepší, než vůbec nevalidovat nebo validovat jen číselný formát, jak se tu v komentářích doporučuje.

B Sheep • před 11 let

Pekny copy-paste, slystel jste nekdy o DRY ?

Tomáš Piňos • před 11 let

Unit test pěkný. Ale konkrétně u RČ bych právě z důvodu existence výjimek raději podle specifikace nevalidoval. Maximálně strukturu ("musí být ve tvaru 5-6 číslic / 4 číslice"). Dávám přednost tomu, když systém raději dovolí zadat i bizarní RČ než aby nedovolil zadat reálně existující RČ odporující specifikaci. Hezký by byl pro nevalidní RČ warning, ale ne blokace.

banterCZ • před 11 let

Setkal ses na to vašem systému s nějakou výjimkou z daných pravidel?

Tomáš Záluský • před 11 let

 Pro kontrolu čísla, které se tváří jako rodné číslo, je to asi užitečné. Ale umím si představit, že když ten test neprojde, tak řešením pravděpodobně nebude oprava chyby validátoru, ale doplnění nějaké výjimky do business logiky, jak psal Wefwefwe.

Osobně je mi na testech tohoto typu nepříjemná jejich rozvláčnost, preferuji raději pomocnou metodu a zápis

@Test public void empty                () {t(false,""          );}
@Test public void numberFormatException() {t(false,"x123456789");}

ideálně zformátovaný i do sloupců (code formatting conventions nejsou dogma).

Jan33 • před 11 let

 Pak ale nepotřebujete Javu, ale nějaký úspornější jazyk typu Groovy. Váš příklad je velmi nepříjemný v tom, že když spadne, není jasné na jakém místě. Absence zpráv v assertech je jen další hřebíček. Takový test bych po vás luštit nechtěl.

Tomáš Záluský • před 11 let

Možná Vašim námitkám nerozumím, ale ani jedna mi nepřijde opodstatněná. Dodávám, jak by vypadala metoda t:

private void t(boolean expected,String input) {
    boolean actual = validator.isValid(input);
    String msg = String.format("chyba pro %s, ocekavano %s, vysledek %s",input,expected,actual);
    assertEquals(msg,expected,actual);
}

- Když test spadne, je místo jasné ze stacktracu. kde je název test metody i řádek. Jen je tam o 1 stackframe víc. Trochu nečitelnější by to bylo při více volání t v rámci jednoho @Testu, obzvlášť kdyby byly na jednom řádku, ale to já také nepovažuji za dobré.
- Absence zpráv v assertech je stejný problém u původního jako u mého kódu.
- K luštění kódu - tady na blogu to není v monospaced fontu, ale v IDE ve spojení s blokovým výběrem je to podle mne zápis, který je velmi efektivní jak pro čtení, tak pro editaci. Metoda t se může jmenovat výstižněji.

Podle mě tady jde jen o dodržení DRY principu, výhody přechodu na typově slabý jazyk mi pro tento případ přijdou přinejmenším diskutabilní.

banterCZ • před 11 let

Groovy bohužel ještě není v Java komunitě tolik rozšířené, tak jsem pro názornost zvolil Javu.

banterCZ • před 11 let

Díky za nápad.

Tibor Mucha • před 11 let

 public class RCValidatorTest {

    private RCValidator validator;
    private boolean expectedIsValid;
    private String validatorInput;
    private String expectingMessage;

    public RCValidatorTest(     String validatorInput,boolean expectedIsValid,     String expectingMessage) {
      this.expectedIsValid = expectedIsValid;
      this.validatorInput = validatorInput;
      this.expectingMessage = expectingMessage;
    }
    public RCValidatorTest(     String validatorInput,boolean expectedIsValid) {
      this.expectedIsValid = expectedIsValid;
      this.validatorInput = validatorInput;
    }

    @Before
    public void setUp() {
        validator = new RCValidator();
    }
    @Parameters
        public static Collection<object[]> getTestData() {
        Collection<object[]> ret = new ArrayList<object[]>();
        ret.add(new Object[] { "x123456789", false, "maju byt iba cisla" });
        ret.add(new Object[] { "7310285169",true, "ukazkove RC"});
        ret.add(new Object[] { "7310285169",true}); //pouzi autgenerovany fail masage
        ....        
        return ret;
        }

    @Test
    public void testIsValid() {
        boolean actual = validator.isValid(validatorInput);
        if (actaul != expectedIsValid) {
            String msg = expectingMessage;
            if (msg == null)
            String.format("ocakaval ze rodne cislo '%s' je %s ",validatorInput,expectedIsValid)
            fail(msg);
        }
          
        assertFalse(result);
    }
}

Guido • před 11 let

Je to hrozně dlouhý ;-)

Asi bych ty testovaný hodnoty naládovat do nějaké kolekce nebo mapy a nechal to prosvištět je dvěma testy - dobrý RČ a špatný RČ.

Nebo bych zkusil v Javě najít něco jako tabulková fakta:
https://github.com/marick/M...

banterCZ • před 11 let

Ano, je to dlouhé. Na druhou stranu, když máš test s deseti asserty a první padne, tak ho opravíš, spustíš a třeba druhý padne. Takhle vidíš výsledky všech assertů paralelně.

Aa • před 11 let

ne vzdy, ale casto se zadava rodne cislo jako soucast formulare s vice  osobnimi udaji. U samotneho validatoru RC to smysl nema, ale jinak jeste lze porovnavat zadanou hodnotu s udajem o pohlavi

banterCZ • před 11 let

V rámci user experience bych neprudil s vyplňováním údajů, které lze odvodil. Proto bych datum narození a pohlaví odvozoval z rodného čísla.

Jan33 • před 11 let

Zajímalo by mě, z jakého důvodu assertujete result a ne rovnou výsledek isValid(String)?

Pak bych také vylepšil názvy testů, když už je máte takhle rozdělené, a nebo alespoň bych v assertu použil message.
 
Totiž "Selhal oldValid9" - není moc návodné co se vlastně stalo.

Wefwefwe • před 11 let

Moc never tomu co se pise. Napriklad u naturalizovanych cizincu je pouzito puvodni cislo pasu jako rodne cislo. Jindy urednik na matrice proste udelal chybu. A jsou i lide kteri jsou obcany CR, ale rodne cislo proste nemaji.

banterCZ • před 11 let

Skutečně jste se setkal s nějakým cizincem, který měl místo RČ původní číslo pasu?

Wefwefwe • před 11 let

Pocital jsem mzdy, tak o tom vim dost. Probiralo se to o Dagiho na blogu asi pet let zpatky.