vežbe -xiinedelja-...

Post on 25-Jul-2020

12 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Vežbe - XII nedelja -Testiranje veb aplikacija

Dražen Drašković, docentUniverzitet u Beograd – Elektrotehnički fakultetOdsek za softversko inženjerstvo

Kod tehnika crne kutije analiziramo samo funkcionalnosti na osnovu funkcionalne specifikacije definisanih zahteva

Koristimo iz projekta:Dokument projektni zadatak (iz faze 1)

Specifikaciju svih slučajeva upotrebe (iz faze 2)

Primenjujemo metodu klasa ekvivalencije (eng. Equivalence class partitioning)

Realizujemo test plana sa test primerima

Automatizovano testiranje korišćenjem nekog alata i provera ponašanja u različitim pregledačima

Ideja: podela ulaznih podataka na podskupove (klase)

Svi ulazni podaci koji daju iste (slične) rezultate pripadaju istoj reprezentativnoj klasi

Idealni slučaj: podskupovi međusobno disjunktni i pokrivaju ceo skup ulaznih podataka

Za svaki uslov se posmatraju dve grupe klasa:Legalne klase - obuhvataju ispravne situacije (ulazne podatke)

Nelegalne klase - obuhvataju sve ostale situacije (ulazne podatke)

Prednost ovog metoda: vreme potrebno za testiranje

Ulazni podatak na osnovu opsega:jedna legalna klasa (unutar opsega)

dve nelegalne klase (levo i desno od opsega)

Primer: mesec uzima broj iz opsega 1-12

Ulazni podatak na osnovu dužine ili formatajedna legalna klasa (tačan broj karaktera/cifara)

dve nelegalne klase (za manji/veći broj karaktera)

Primer: JMBG ima tačno 13 cifara

Tačno definisan skup ulaznih podatakapo jedna legalna klasa (za svaku pojedinačnu vrednost) i jedna zajednička nelegalna klasa

Uslov obaveznosti za ulazni podatakjedna legalna klasa za ispravnu vrednost

i bar jedna nelegalna klasa za neispravnu vrednost

U slučaju da program ne tretira jednako sve elemente neke klase ekvivalencije, nju treba podeliti na više manjih klasa

Test plan (eng. Test suite) sastoji se iz test primera (eng. Test case)

Svaki test primer treba da bude dizajniran pre implementacije i izvršavanja testa

Nakon što se odrede klase ekvivalencije, formiraju se test primeri za:

sve legalne klase ekvivalencije (cilj je da se što manje test primera primeni na što više klasa ekvivalencije)

sve nelegalne klase ekvivalencije (za svaku nelegalnu klasu po jedan test primer, da se ne bi desilo da jedan test primer koji nije regularan maskira neki drugi test primer)

Opciono možemo koristiti i metod graničnih slučajeva (eng. Boundary value testing)

Metod klasa ekvivalencije proširujemo, tako da se fokusiramo na granice svake klase, jer se tu krije veliki broj grešaka

Primer: popust na avio karte u kompaniji Air Serbia, za decu do 7 godina, da li je popust ako dete nije napunilo 7, ili u celoj kalendarskoj godini, dok ne napuni 8 god.

Identifikujemo klase ekvivalencije, a zatim identifikujemo granice svake klase ekvivalencije.

Pravimo test primer za svaku graničnu vrednost tako što biramo:

Jednu tačku A na samoj granici

Jednu tačku B ispod granice

Jednu tačku C iznad granice

Tačke B i C treba vrlo pažljivo odabrati i te tačke zavise od jedinice vrednosti podatka koji analiziramo. Takve tačke mogu biti i u drugim klasama ekvivalencije, pa voditi računa da testovi NE BUDU DUPLIRANI.

Manuelno testiranje

Automatsko GUItestiranje (web automation testing)

Primer: - Selenium IDE framework- iMacros

Postoji i Selenium WebDriver:

kompaktni OO API

za različite veb pregledače(cross browser testing)

U literaturi još i kao: strukturno testiranje (eng. structural testing),

testiranje čistom kutijom (eng. clear box),

otvorenom kutijom (eng. open box),

staklenom/transparentnom kutijom (eng. glass box / transparent box),

zasnovano na kodu (eng. code-based testing)

Primarni izvor za projektovanje testova je izvorni kod sa fokusom na tok kontrole i tok podataka

Cilj strukturnog testiranja nije da se izvrše sve moguće funkcije programa, već da se izvrše/aktiviraju različite programske i strukture podataka u programu

Grafovi kontrole toka predstavljaju vizuelnu reprezentaciju strukture koda nekog programa. Izvršavanjem programa (na primer, za neke test podatke) vrši se izbor neke putanje u grafu.

Vrste:Pokrivenost iskaza (eng. Statement Coverage) = pokrivenost instrukcija ili pokrivenost koda

Pokrivenost odluka ili pokrivenost grana (eng. Decision or Branch Coverage)

Pokrivenost uslova (eng. Condition Coverage)

Pokrivenost višestrukih uslova (eng. Multiple Condition Coverage)

Minimalna pokrivenost višestrukih uslova (eng. Minimal Multiple Condition Coverage)

Pokrivenost odluka i uslova (eng. Decision/Condition Coverage)

Modifikovana pokrivenost odluka i uslova (MC/DC)

Jedinično testiranje (eng. unit testing)

Integraciono testirane (eng. integration testing)

Sistemsko testiranje (eng. system testing)

PHPUnit je alat otvorenog koda za automatizovano jedinično testiranje PHP koda

Alat je napisan u PHP-u i koncepcijski zasnovanna JUnit-u (za Javu)

Najnovija verzija: PHPUnit ver. 9.1 (februar 2020) baziran za testiranje PHP 7.3 ili 7.4

Instalacija po projektu, ne globalno!

Nema potrebe da bude na veb serveru. Zašto?

Dokumentacija dostupna na:https://phpunit.readthedocs.io/en/9.1/

Šta dobijamo jediničnim testovima?identifikovanje grešaka i ispravke u kodu

refaktorizacija koda

dokumentacija za najmanje elemente programskog koda (koji se testiraju)

Da bi sve ovo postigli, moramo da pokrijemo sve putanje u kodu

Jedan test obično pokrije jednu putanju u funkciji

Analiza pokrivenosti koda (code coverage)

Izveštaj o pokrivenosti koda zahteva Xdebug (ver. 2.7.0)

Tipovi obuhvaćeni kroz PHPUnit:Pokrivenost iskaza (Line Coverage)

Pokrivenost funkcija (Function/Method Coverage)

Pokrivenost klasa i osobina (Class and Trait Coverage)

Pokrivenost iskompajliranog koda (Opcode Coverage)

Pokrivenost grana (Branch Coverage)

Pokrivenost bazičnih putanja (Path Coverage)

Change Risk Anti-Patterns (CRAP) Index

Automatsko generisanje izveštaja o izvršenimtestovima u XML formatu

Analiza pokrivenosti koda

Prihvatanje proizvoljnog broja argumenata u testovima (parametrizovani testovi)

Podrška za nekompletne testove (tela nekih test funkcija su prazna) i preskakanje testova

Generisanje skeleta test koda za postojeći kod

Podrška za mock objekte

Integracija sa raznim alatima

Cilj je da postoji dobra struktura, tako da možemo pokretati odvojeno grupe:

testovi za ceo projekat

testovi za sve klase neke komponente

samo testovi za jednu klasu

Obavezno odvojeno izvorni kod i testovi$ phpunit --bootstrap src/autoload.php tests

PHPUnit 9.1.0 by Sebastian Bergmann and

contributors.

.................................

Time: 636 ms, Memory: 3.50Mb

OK (33 tests, 52 assertions)

phpunit.xml - XML format fajla i navodimo test primere<phpunit bootstrap="src/autoload.php">

<testsuites>

<testsuite name="grupa1">

<file>tests/IntlFormatterTest.php</file>

<file>tests/MoneyTest.php</file>

<file>tests/CurrencyTest.php</file>

</testsuite>

</testsuites>

</phpunit>

<phpunit bootstrap="src/autoload.php">

<testsuites>

<testsuite name="grupa2">

<directory>tests</directory>

</testsuite>

</testsuites>

</phpunit>

Test sa višestrukim zavisnostima Parametrizovani testovi

$ phpunit DataTest

PHPUnit 9.1.0 by Sebastian Bergmann and contributors.

..F... 6 / 6 (100%)

Time: 0 seconds, Memory: 5.75Mb

There was 1 failure:

1) DataTest::testAdd with data set #3 (1, 1, 3)

Failed asserting that 2 is identical to 3.

/home/sb/DataTest.php:12

FAILURES!

Tests: 6, Assertions: 6, Failures: 1.

Izlaz testa:

$ phpunit --verbose SampleTest

PHPUnit 9.1.0 by Sebastian Bergmann and contributors.

I

Time: 0 seconds, Memory: 3.95Mb

Izlaz testa:There was 1 incomplete test:

1) SampleTest::testSomething

This test has not been implemented yet.

/home/sb/SampleTest.php:12

OK, but incomplete or skipped tests!

Tests: 1, Assertions: 1, Incomplete: 1.

Nekompletan test

Preskakanje testa

$ phpunit --verbose DatabaseTest

PHPUnit 9.1.0 by Sebastian Bergmann and contributors.

S

Time: 0 seconds, Memory: 3.95Mb

There was 1 skipped test:

1) DatabaseTest::testConnection

The MySQLi extension is not available.

/home/sb/DatabaseTest.php:9

OK, but incomplete or skipped tests!

Tests: 1, Assertions: 0, Skipped: 1.

Izlaz testa:

Cilj: realni deo koda, tzv. depended-on component(DOC) zameniti sa test dublerom, koji se ponaša isto kao pravi deo koda.

Koriste se metode:createStub($type),

createMock($type),

getMockBuilder($type).

Vraćaju objekat test dublera za specifični tip (klasu)

Podrazumevano, sve metode originalne klase se zamenjuju sa dummy implementacijama koje vraćaju vrednost null

Praksa zamene objekata sa test dublerom, koji opciono vraća predefinisane vrednosti zove se stubbing.

Stub se koristi da zameni realnu komponentu od koje zavisi sistem i proces testiranja, tako da test ima kontrolne tačke za indirektne ulaze u sistem

Na taj način, sistem će pomoću stubs izvršiti i putanje, koje inače ne bi mogao

Izuzetak: (ako se metoda baš zove method)$stub->expects($this->any())->method('doSomething')->willReturn('foo');

Praksa zamene objekata sa test dublerom, koji potvrđuje očekivanja na primer tvrdeći da je metoda pozvana, zove se mocking.

Mock se koristi kao posmatrana tačka za verifikaciju indirektnih izlaza sistema koji se testira

Mock objekat uključuje funkcionalnost test stub-a, u koji on mora vratiti vrednost sistemu, ako nisu svi pokrenuti testovi pali

PHPUnit se može instalirati korišćenjemPHP Archive (PHAR), njenim preuzimanjem i raspakivanjem:

Može se dodati u projekat preko Composer-a

Rezultati se najčešće prikazuju u izveštaju o testiranju, koji je takođe u XML formatu kod PHPUnit alata (slično kao kod JUnit za Apache Ant)

Ako postoje greške, one će se jasno prikazati kao failure ili error

<?xml version="1.0" encoding="UTF-8"?>

<coverage generated="1184835473" phpunit="3.6.0">

<project name="BankAccountTest" timestamp="1184835473">

<file name="/home/sb/BankAccount.php">

<class name="BankAccountException">

<metrics methods="0" coveredmethods="0" statements="0"

coveredstatements="0" elements="0" coveredelements="0"/>

</class>

<class name="BankAccount">

<metrics methods="4" coveredmethods="4" statements="13"

coveredstatements="5" elements="17" coveredelements="9"/>

</class>

<line num="77" type="method" count="3"/>

<line num="79" type="stmt" count="3"/>

<line num="89" type="method" count="2"/>

</file>

<metrics files="1" loc="126" ncloc="37" classes="2" methods="4"

coveredmethods="4" statements="13" coveredstatements="5"

elements="17" coveredelements="9"/>

</project>

</coverage>

Assertation metode se deklarišu statičke i mogu se pozvati iz bilo kog konteksta za instancu:

PHPUnit\Framework\Assert::assertTrue()

$this->assertTrue() ili self::assertTrue(),

Još lakše se može pozvati kao omotač globalne funkcije, u bilo kom kontekstu, npr. assertTrue()

Samo uključiti: src/Framework/Assert/Functions.php

Šta je bolje koristiti?Programeri najviše vole: $this->assertTrue()

Sve funkcije su oblika: assertNesto

assertArrayHasKey()

assertClassHasAttribute()

assertContains()

assertCount()

assertDirectoryExists()

assertDirectoryIsReadable()

assertDirectoryIsWritable()

assertEmpty()

assertEquals()

assertFalse()

assertTrue()

assertFileExists()

assertGreaterThan()

assertGreaterThanOrEqual()

assertInfinite()

assertIsArray()

assertIsFloat()

assertIsInt()

assertIsNumeric()

assertIsObject()

assertIsString()

assertLessThan()

assertNan()

assertNull()

assertMatchesRegularExpression()

assertStringMatchesFormat()

assertXmlFileEqualsXmlFile()

assertEquals(mixed $expected, mixed $actual

[, string $message=‘’])

Prijavljuje neuspeh, ako se $expected i $actual razlikuju

$message je opciona poruka koja se ispisuje u slučaju neuspeha

Inverzna f-ja: assertNotEquals, sa istim argumentima

F-ja: assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta

[, string $message = ''])

$delta je opciona numerička vrednost koja se koristi kada su $expected i $actual nekog numeričkog tipa. Tada se neuspeh prijavljuje ako nije zadovoljen uslov: $actual € [$expected - delta, $expected + $delta]

assertContains(mixed $needle,

iterable $haystack[, string $message = ''])

Prijavljuje neuspeh, ako $haystack ne sadrži $needle, pričemu ove promenljive mogu biti stringovi, ili je $haystack niz, a $needle nekog prostog tipa

$message je opciona poruka, u slučaju neuspeha

Primer:<?php

use PHPUnit\Framework\TestCase;

class ContainsTest extends TestCase {

public function testFailure(){

$this->assertContains(4, [1, 2, 3]);

}

}

Inverzna f-ja:assertNotContains(mixed $needle,

iterable $haystack[, string $message = ''])

Prijavljuje neuspeh, ako $haystack sadrži $needle

Postoje još neke funkcije:

assertStringContainsString(string $needle,

string $haystack[, string $message = ’’])

Ova funkcija ispisuje grešku u vidu poruke ukoliko argument $needle nije podstring argumenta $haystack

Inverzna: assertStringNotContainsString()

Ako zanemarujemo mala i velika slova:assertStringContainsStringIgnoringCase(

string $needle, string $haystack[,

string $message = ''])

assertNull(mixed $variable[,

string $message = ''])

Prijavljuje neuspeh, ako $variable nije NULL

$message je opciona poruka, ispisuje se u slučajuneuspeha

Inverzna f-ja: assertNotNull()

Prijavljajuje neuspeh, ako je $variable NULL.

assertTrue(bool $condition

[, string $message = ''])

Prijavljuje neuspeh, ako $condition nije true

$message je opciona poruka, u slučaju neuspeha

Inverzna f-ja: assertNotTrue()

iliassertFalse(bool $condition

[, string $message = ’’])

Prijavljuje neuspeh, ako $condition nije false.

assertMatchesRegularExpression(

string $pattern, string $tekst[,

string $message = ''])

Prijavljuje neuspeh, ako se string $tekst ne poklapa sa regularnim izrazom $pattern

$message je opciona poruka koja se ispisujeu slučaju neuspeha

Inverzna funkcija:assertDoesNotMatchRegularExpression()

sa istim argumentima

assertIsObject($actual[, $message = ''])

assertIsString($actual[, $message = ’’])

assertIsInt($actual[, $message = ’’])

assertIsFloat($actual[, $message = ’’])

assertIsBool($actual[, $message = ’’])

assertIsResource($actual[, $message = ’’])

Za nizove:assertArrayHasKey(mixed $key,

array $array [, string $message = ’’])

assertCount($expectedCount, $haystack [,

string $message = ''])

assertClassHasAttribute(string $imeAtributa,

string $imeKlase [, string $message = ''])

Prijavljuje neuspeh i ispisuje poruku,ako ne postoji$imeKlase::imeAtributa

Inverzna f-ja sa istim argumentima: assertClassNotHasAttribute()

Primer:<?php

use PHPUnit\Framework\TestCase;

class ClassHasAttributeTest extends TestCase {

public function testFailure(){

$this->assertClassHasAttribute(’atr', stdClass::klasa);

}

}

@author

@after

@afterClass

@backupGlobals

@backupStaticAttributes

@before

@beforeClass

@codeCoverageIgnore

@covers

@coversDefaultClass

@coversNothing

@dataProvider

@depends

@doesNotPerformAssertions

@group

@large

@medium

@preserveGlobalState

@requires

@runTestsInSeparate-

Processes

@runInSeparateProcess

@small

@test

@testdox

@testWith

@ticket

@uses

Inicijalizacija:$this->load->library('unit_test');

Pokretanje testa:$test = 1 + 1;

$expected_result = 2;

$test_name = 'Adds one plus one';

$this->unit->run($test, $expected_result,

$test_name);

Ispisivanje jednog testa:echo $this->unit->run($test,

$expected_result);

Ispisivanje izveštaja svih testova:echo $this->unit->report();

Ispisivanje izveštaja u vidu HTML tabele:echo $this->unit->result();

Kada se pokrene rezultat izvršavanja jediničnog testa prikazuje sledeće podatke:

Test Name (test_name)

Test Datatype (test_datatype)

Expected Datatype (res_datatype)

Result (result)

File Name (file)

Line Number (line)

Any notes you entered for the test (notes)

Izveštaj se može uređivati:$this->unit->set_test_items(array('test_name',

'result'));

U trenutku pisanja programskog koda (test driven development)

Na taj način utvrđujemo manje bagove u kodu još tokom razvoja

Praksa je da programeri ne testiraju svoj kod, jer tako previde svoje greške, već da deo koda koji je on implementirao, testira drugi programer ili osoba iz tima koja se bavi samo testiranjem (softverski tester)

Na našem projektu:u toku faze implementacije: pišemo jedinične testove i testiramo najniže delove koda (bela kutija)

nakon završetka implementacije: pišemo automatizovane testove i testiramo celokupan sistem (crna kutija)

PHP osnovna stranica za dokumentaciju:http://www.php.net

PHP Unit dokumentacija:https://phpunit.readthedocs.io/en/9.1/index.html

Testiranje softvera, sajt predmeta na ETF-u:http://si3ts.etf.bg.ac.rs

Jedinično testiranje u okviruCodeIgniter radnog okvira:https://codeigniter.com/userguide3/libraries/unit_testing.html

top related