Help:Pickle/nb

Pickle er et prosjekt for å integrere kontinuerlig testing i et miljø for kontinuerlig integrasjon, slik som Wikipedia som bruker Lua-skript. På Wikipedia brukes Lua for å implementere avanserte maler, og samme løsning er brukt på mange andre nettsteder og prosjekter. Kontinuerlig testing er et kjerneelement i kontinuerlig levering, som er veldig viktig for nettsteder slik som Wikipedia som må være oppe og kjøre 24×7. Pickle bruker blant annet spec-type testing, som kan bli beskrevet som en variant av enhetstesting, eller hvordan lage (bygge) tingen rett. Senere vil Pickle muligens bli utvidet med step-type testing, eller hvordan bygge rett ting. Hva som skal bygges, og hvordan bygge det, er ikke det eneste viktige. Det er også ekstremt viktig å redusere den samlede risikoen forbundet med å gjøre Lua-utvikling i et aktivt Mediawiki-prosjekt.

På engelsk er pickle en type grønnsak som har gjennomgått sylting, for eksempel sylteagurk, men som også er navnet på Gherkin-språket for å gjøre step-type testing. Samtidig så plukker du på koden, prøver på å dissekere den, i en kontinuerlig prosess for å finne feil og korrigere dem.

Bakgrunn
Testing lar oss si noe kvalitativt om programvaren, det vil si modulene i wikien, slik som antall og typer av kjente defekter, spesielt for funksjonelle krav. Det hjelper utviklerne å identifisere og fikse defekter under utvikling, men bygger også nettsamfunnets tiltro til den endelige modulen. Når noen senere ønsker å bruke modulen som del av en mal, da kan han sjekke resultatene, og muligens bli forsikret om at dette er faktisk en god modul før han kaller modulen fra malen. Hvis noe hender senere, muligens som følge av en feil i en annen inkludert modul, så vil forhåpentligvis testene identifisere de underliggende årsakene til problemet.

I denne løsningen, så kan alle lage de nødvendige testene, men det må forventes at brukeren som utviklet koden vil utvikle testene. Den brukeren vet best hva som må testes og hvordan teste det. Du aksepterer ikke halvferdig kode, og du bør heller ikke akseptere halvferdige tester. Likevel er det enkelt å glemme noen viktige tilfeller, og når du ser slike tilfeller så legg dem til! Bedre testdekning betyr færre defekter nå og i fremtiden.

Den grunnleggende ideen
Når en tester (det vil si en pickle) har kjørt alle sine tester for et spesifikt testsubjekt (det vil si biblioteket eller modulen), og alle testene er gode, da vil den siden bli merket som god både med en sideindikator og med en sporingskategori. Hvis tilstanden endres så vil det også bli lagd loggoppføringer. Hvis testene starter å feile av enhver grunn så vil de bli flagget som feilet av en sideindikator, og bli lagt i en kategori for feilede biblioteker. If the state changed from some other state into a failed state, then there will also be a log entry. Together this is the primary mechanisms for tracking down failing libs.

The outer frame (world) should only try to tests a single testee, and because of this there should only be a single. It is completely valid to have several, but it won't really make sense while testing single libs. This can be rephrased as a change of, which would imply a change of data provided to the testee. Such a change will be given as a descriptive string, where data is extracted from that string. Those extracted data snippets will then be cast to correct type and provided to the frame (world). Most of the time it will not be necessary to create separate context and it will only be a  with a number of.

Assume that there is a module for the ubiquitous "Hello World". This code looks like the example code 1

Example code 1, an example of the ubiquitous "Hello World". There is nothing extraordinary with the definition this module.

The code for testing this code looks like the example code 2

Example code 2, example of a spec-style test. There is (will be) both an implicit and explicit form of calls on subjects.

Note that the inner  takes a string as argument and that this string has an inner string "Hello". This string is delivered to the "frame" ("world") and is used in the test. The outer  has also an inner string in the description, but this is thrown away.

The first  tries to attach the test to the correct lib, that is the testee, and will store this as the. This can be tested by comparing it to an expectation. The expectation is what you want a value from the subject to be, not the subject itself. This makes it possible to make a model of what the subject should be. You compare the model with the, to valuate it in some respect. How the valuation is done, and its outcome, is then reported. If the valuation is good for all valuations, then the overall state for the testee is set as good.

Statements that are truthy will be stated as  something, but what about statements that should be falsy? Those statements use a function. They are very similar to, but they have their final valuation negated. This makes it simple to make a statement that the code should not fulfil. A closer inspection reveals that each test is a row in a Karnaugh map, with  being rows with a truthy outcome and   those with a falsy outcome.

Because the columns in a Karnaugh map represents the branching decisions in the code, that is the nodes in a control flow graph, while the rows represents valuated paths, and that our tests only hits a fraction of the possible valuations, the actual valuations must be as representative as possible. Usually, we will put great effort into identifying border and corner cases, but if the code is badly written it could be very difficult or even impossible to hit all alternate valuations from the columns. Often the best we can do is to try to cover most of the branches (branch coverage, "edge cases"), that is the number of tests should be of the same order as cyclomatic complexity or close to it but still lower, or if we are adventurous we can head for independent paths (path coverage).