Vra

Hierdie is'n moeilike en oop-einde vraag wat ek weet, maar ek het gedink ek wil gooi dit op die vloer en sien as iemand het enige interessante voorstelle.

Ek het'n kode-kragopwekker wat ons python koppelvlak om ons C++ - kode (wat gegenereer word via SLUK) en genereer'n kode wat nodig is om bloot hierdie as WebServices.Wanneer ek ontwikkel hierdie kode ek het dit gedoen met behulp van TDD, maar ek het gevind dat my toetse te wees bros soos die hel.Want elke toets in wese wou om te verifieer dat vir'n gegewe bietjie van insette kode (wat gebeur om te wees'n C++ kop) ek wil'n gegewe bietjie van outputted die kode wat ek geskryf het'n klein enjin wat lees toets definisies van XML insette lêers en genereer toets gevalle van hierdie verwagtinge.

Die probleem is ek skrik gaan in om die kode te verander op alle.Dit en die feit dat die eenheid toetse self is'n:kompleks is, en b:bros.

So ek probeer om te dink van alternatiewe benaderings tot hierdie probleem, en dit lyk my ek is miskien die aanpak van dit op die verkeerde manier.Miskien het ek nodig het om meer te fokus op die uitkoms, NAAMLIK:beteken die kode wat ek genereer eintlik hardloop en doen wat ek dit wil hê, eerder as om, nie die kode lyk die manier wat ek dit wil hê.

Het iemand het'n ervaring van iets soortgelyk aan dit wat hulle sou omgee om te deel?

Was dit nuttig?

Oplossing

Ek het begin skryf 'n opsomming van my ondervinding met my eie kode kragopwekker, dan teruggegaan en weer lees jou vraag en gevind jy reeds aangeraak dieselfde kwessies jouself, fokus op die uitvoering resultate in plaas van die kode uitleg / kyk.

Probleem is, dit is moeilik om te toets, die gegenereerde kode kan nie geskik wees om werklik uit te voer in die omgewing van die eenheid toets stelsel, en hoe kan jy die verwagte resultate te enkodeer?

Ek het gevind dat jy nodig het om af te breek die kode kragopwekker in kleiner stukkies en eenheid toets dié. Eenheid toets van 'n volle-kode kragopwekker is meer soos integrasie toets as eenheid toets as jy my vra.

Ander wenke

Onthou dat "eenheid toets" is net een soort van toetsing. Jy moet in staat wees om eenheid toets die interne stukke van jou kode kragopwekker. Wat jy regtig kyk na hier is toets stelsel vlak (ook bekend as regressie toets). Dit is nie net semantiek ... daar verskillende ingesteldheid, benaderings, verwagtinge, ens Dit is beslis meer werk, maar jy waarskynlik nodig het om die bullet te byt en die opstel van 'n end-tot-end regressie toets suite: vaste C ++ lêers -> sluk koppelvlakke -> python modules -> bekend uitset. Jy wil regtig die bekende insette (vaste C ++ kode) teen verwagte uitset kyk (wat kom uit van die finale Python program). Nagaan van die kode kragopwekker resultate direk sou wees soos diffing voorwerp lêers ...

Ja, resultate is die enigste ding wat saak maak. Die ware karwei skryf 'n raamwerk wat dit moontlik maak jou gegenereerde kode om onafhanklik te loop ... spandeer jou tyd daar.

As jy deel is van * nux wat jy kan oorweeg storting die unittest raamwerk ten gunste van 'n bash script of makefile. op vensters wat jy kan oorweeg die bou van 'n dop app / funksie wat die kragopwekker loop en dan gebruik die kode (as 'n ander proses) en unittest dat.

'n derde opsie sou wees om die kode te genereer en dan 'n app uit dit wat niks anders as 'n unittest sluit bou. Weer jy sal 'n dop script of iets anders nodig het om hierdie hardloop vir elke insette. Oor hoe om die verwagte gedrag enkodeer, dit val my op dat dit in veel dieselfde manier gedoen kan word as jy sou vir die C ++ kode net die gebruik van die gegenereerde koppelvlak eerder as die C ++ een.

Wou net om te wys dat jy nog fyn toets kan bereik, terwyl die verifikasie van die resultate: jy kan individuele stukke kode te toets deur nes hulle binne 'n paar opstel en verifikasie kode:

int x = 0;
GENERATED_CODE
assert(x == 100);

Met dien verstande dat jy jou gegenereerde kode saamgestel uit kleiner stukke, en die stukke nie gereeld verander, kan jy meer voorwaardes uit te oefen en toets 'n bietjie beter, en hopelik verhoed dat al jou toetse te breek wanneer jy besonderhede van een stuk verander.

Eenheid toets is net dat die toets van 'n spesifieke eenheid. So as jy 'n spesifikasie vir klas A skryf, is dit ideaal as klas A nie die werklike konkrete weergawes van klas B en C.

het nie

Ok ek opgemerk daarna die tag vir hierdie vraag sluit C ++ / Python, maar die beginsels is dieselfde:

    public class A : InterfaceA 
    {   
      InterfaceB b;

      InterfaceC c;

      public A(InterfaceB b, InterfaceC c)   {
          this._b = b;
          this._c = c;   }

      public string SomeOperation(string input)   
      {
          return this._b.SomeOtherOperation(input) 
               + this._c.EvenAnotherOperation(input); 
      } 
    }

As gevolg van bogenoemde System A spuit koppelvlakke na stelsels B en C, jy kan eenheid toets net stelsel A, sonder werklike funksie uitgevoer word deur enige ander stelsel. Dit is eenheid toets.

Hier is 'n slim manier om nader 'n Stelsel van die skepping tot voltooiing, met 'n ander Wanneer spesifikasie vir elke stukkie van gedrag:

public class When_system_A_has_some_operation_called_with_valid_input : SystemASpecification
{
    private string _actualString;

    private string _expectedString;

    private string _input;

    private string _returnB;

    private string _returnC;

    [It]
    public void Should_return_the_expected_string()
    {
        _actualString.Should().Be.EqualTo(this._expectedString);
    }

    public override void GivenThat()
    {
        var randomGenerator = new RandomGenerator();
        this._input = randomGenerator.Generate<string>();
        this._returnB = randomGenerator.Generate<string>();
        this._returnC = randomGenerator.Generate<string>();

        Dep<InterfaceB>().Stub(b => b.SomeOtherOperation(_input))
                         .Return(this._returnB);
        Dep<InterfaceC>().Stub(c => c.EvenAnotherOperation(_input))
                         .Return(this._returnC);

        this._expectedString = this._returnB + this._returnC;
    }

    public override void WhenIRun()
    {
        this._actualString = Sut.SomeOperation(this._input);
    }
}

So ten slotte, 'n enkele eenheid / spesifikasie kan verskeie gedrag het, en die spesifikasie groei as jy die eenheid / sisteem te ontwikkel; en as jou stelsel onder toets hang af van ander konkrete stelsels binne dit, kyk uit.

My aanbeveling sou wees om uit te vind 'n stel van bekende input-output resultate, soos sommige eenvoudiger gevalle dat jy reeds in plek, en eenheid toets die kode wat geproduseer word . Dit is heeltemal moontlik dat as jy die kragopwekker wat die presiese string wat geproduseer word effens anders kan wees verander ... maar wat jy regtig omgee is of dit geïnterpreteer word op dieselfde manier. Dus, as jy die resultate te toets as jy daardie kode sal toets as dit jou funksie, sal jy uitvind of dit daarin slaag om in die maniere waarop jy wil.

Basies, wat jy regtig wil weet, is of jou kragopwekker sal produseer wat jy verwag sonder om fisies te toets elke moontlike kombinasie (ook: onmoontlik). Deur te verseker dat jou kragopwekker is in ooreenstemming in die maniere wat jy verwag, kan jy beter dat die kragopwekker sal slaag in al hoe meer komplekse situasies voel.

Op hierdie manier, kan jy ook die opbou van 'n suite van regressie toetse (eenheid toetse wat nodig het om te hou korrek werk). Dit sal jou help om seker te maak dat veranderinge aan jou kragopwekker nie breek ander vorme van kode. Wanneer jy 'n fout wat jou eenheid toetse nie vang teëkom, wil jy dalk om in te sluit dit aan soortgelyke skade te voorkom.

Ek vind dat jy nodig het om te toets wat jy genereer meer as hoe jy dit genereer.

In my geval, die program genereer baie verskillende tipes van die kode (C#, HTML, SCSS, JS, ens.) wat stel in'n web aansoek.Die beste manier wat ek gevind het om te verminder regressie foute algehele is om die toets van die web aansoek self, nie deur die toets van die generator.

Moenie my verkeerd verstaan nie, daar is nog eenheid toetse uitcheck sommige van die kragopwekker kode, maar ons grootste bang vir ons bok is UI toetse op die gegenereerde app self.

Sedert ons is die opwekking van dit wat ons genereer ook'n lekker abstraksie in die JS ons kan gebruik om te programatically die toets van die app.Ons het'n paar idees hier uiteengesit: http://code.tutsplus.com/articles/maintainable-automated-ui-tests--net-35089

Die goeie deel is dat dit regtig toets jou stelsel end-tot-einde, van die kode generasie uit na wat jy eintlik genereer.Een keer'n toets druip, sy maklik om te volg dit terug na waar die kragopwekker gebreek het.

Dit is baie soet.

Goeie geluk!

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top