Ningú discuteix la necessitat de realitzar proves per comprovar el correcte funcionament d'una aplicació. El que ja és un altre tema és com realitzar aquestes proves ja que existeixen multitud de formes de fer des del mètodes més tradicionals per fases (sent la fase de proves una fase posterior a les fases de disseny/especificació i implementació de codi) o sistemes completament orientats als tests com TDD o BDD.
Aquest article mira d'explicar els sistemes més coneguts a l'hora de realitzar proves en aplicacions de programari.
Testing és el procés d'avaluació d'un sistema i dels seus components amb l'objectiu de saber si satisfà els requeriments especificats. Amb paraules més simples, realitzar tests és executar un sistema per tal d'identificar errors, funcionalitats no implementades, bugs, etc
According to ANSI/IEEE 1059 standard, Testing can be defined as - A process of analyzing a software item to detect the differences between existing and required conditions (that is defects/errors/bugs) and to evaluate the features of the software item.
Automatitzar els tests d'una aplicació té múltiples objectius i és molt important entendre aquests motius per tal de conèixer (i assumir) la motivació per tal de realitzar una tasca que evidentment genera una feina extra i que per tant necessita d'una justificació. Els tests poden semblar "redundants" o innecessaris sobretot per què com a desenvolupadors ens trobem durant la creació dels tests ens trobem escrivint un codi extra que prova el nostre propi codi i que això ho podem precisament provant el codi sense programar. La gràcia està en:
Recursos:
Solen haver 3 opcions:
Vegeu assertion library
Test Double és un concepte que fa referència a objectes falsos ("fake") que substitueixen als originals (objectes reals que s'utilitzen durant l'execució de l'aplicació) durant la realització dels tests. Els frameworks de test com PHPUnit o PHPSpec ofereixen ajudes per a utilitzar Test Doubles. Per exemple PHPSpec porta incorporat la llibreria Prophecy ( a highly opinionated mocking framework. opinionated = dogmàtico | testarudo).
L'objectiu és la isolation és a dir aconseguir que els tests d'una classe concreta no depenguin dels tests dels seus col·laboradors (o classes de les que depèn).
Veiem alguns conceptes:
Els següents apartats mostren exemples de diferents tipus de Test Doubles amb exemples concrets realitzats amb PHPSpec.
Recursos:
Que vol dir mocking en anglès (en termes no informàtics)? Vegeu les imatges que us mostra Google si cerqueu Mocking:
https://www.google.es/search?q=Mocking&espv=2&biw=1375&bih=767&source=lnms&tbm=isch&sa=X&ei=28H-VL2AOsXXasi0gqAF&ved=0CAYQ_AUoAQ
Té mútliples sentits ([1]) com parodiar, imitar o burlar-se però en termes informàtics farà més referència a simulat, fingit, actuat, pràctica.
Quan realitzem Unit Tests normalment no estem interessats en els objectes o dependències del nostre codi sinó que volem centrar-nos en provar el codi propi i en unitat petites de test. Fàcilment al programar ens trobarem amb el problema de que fer amb estes dependències. Vegeu un exemple, una classe encarregada del registre d'un usuari a una aplicació (web):
En aquest cas si fem un test unitari ens hem de centrar en provar el nostre codi propi i no pas el codi de base de dades ni el d'enviament de emails i per tant farem una simulació (mocking) d'aquestes classes.
Conceptes relacionats que són importants:
Vegeu un exemple al següent projecte de github:
https://github.com/acacha-org/acacha-laracasts-testing-jargon
<?php namespace spec\Acacha\Laracasts\TestingJargon; use PhpSpec\ObjectBehavior; use Prophecy\Argument; use Acacha\Laracasts\TestingJargon\UserRepository; use Acacha\Laracasts\TestingJargon\Mailer; class AcachaRegistersUserSpec extends ObjectBehavior { function let(UserRepository $repository, Mailer $mailer) { $this->beConstructedWith($repository,$mailer); } function it_is_initializable() { $this->shouldHaveType('Acacha\Laracasts\TestingJargon\AcachaRegistersUser'); } function it_creates_a_new_user(UserRepository $repository){ $user = ['username' => 'John','email' => '[email protected]']; $repository->create($user)->shouldBeCalled(); $this->register($user); } function it_sends_a_welcome_email(Mailer $mailer) { $user = ['username' => 'John','email' => '[email protected]']; $mailer->sendWelcome('[email protected]')->shouldBeCalled(); $this->register($user); } }
Recursos
It depends on the process and the associated stakeholders of the project(s). In the IT industry, large companies have a team with responsibilities to evaluate the developed software in context of the given requirements. Moreover, developers also conduct testing which is called Unit Testing. In most cases, the following professionals are involved in testing a system within their respective capacities:
Different companies have different designations for people who test the software on the basis of their experience and knowledge such:
It is not possible to test the software at any time during its cycle. The next two sections state when testing should be started and when to end it during the SDLC.
http://www.tutorialspoint.com/software_testing/software_testing_myths.htm
Dos grans tipus/nivells de tests:
Recursos:
Aquest tipus de tests són realitzats pels desenvolupadors de codi i treballen a baix nivell. Sovint són tests realitzats per als propis desenvolupadors per tal de poder comprovar que el que estan implementat a baix nivell compleix amb la funcionalitat lògica esperada. Aquests tests es realitzen sovint durant la mateix afase de creació de codi i es poden realitzar al mateix temps que s'escriu codi (sovint associat a la idea de Test Driven Development) però per múltiples raons també es pot crear primer codi i després realitzar els tests unitaris. Fins i tot existeixen sistemes com el BDD (Behavious Driven Development) on primer s'especifiquen els tests de funcionalitat i a partir d'aquests es crear el codi, és a dir s'utilitzen els propis tests com a eina de disseny del codi.
Per tant cal tenir en compte que els test unitàries estan relacionats amb els desenvolupadors i no se solen executar en fase posteriors ni hi sol intervindré el equip de test o de Q&A.
Un objectiu important dels test unitaris és la isolació (isolate) és a dir assegurar-se que els tests són independents de les dependències dels objectes de forma que es podin executar de forma unitària o independent. Altres sistemes se solen aplicar a posteriori com els test d'integració per comprovar que els components (unitats) del sistema funcionen correctament junts.
Limitacions
Algunes notes i exemples a mode de resum:
Podeu veure un exemple de Test unitari a:
Algun dels frameworks més coneguts de tests unitaris són:
Recursos:
Algun dels frameworks més coneguts de tests d'integració són:
Recursos
Un test d'acceptació és un test que permet validar/aceptar un codi com a correcte per passar-lo a explotació. En equips de desenvolupament grans aquests tipus de test els realitzar el Quality Assurance Team que s'encarrega de comprovar que l'aplicació compleix amb els requeriments del client final.
Aquests tests es poden realitzar de forma natural/manual o també es poden mirar d'automatitzar utilitzant frameworks específicament dissenyats amb aquest objectiu.
Recursos:
This section is based upon testing an application from its non-functional attributes. Non-functional testing involves testing a software from the requirements which are nonfunctional in nature but important such as performance, security, user interface, etc.
Some of the important and commonly used non-functional testing types are discussed below.
It is mostly used to identify any bottlenecks or performance issues rather than finding bugs in a software. There are different causes that contribute in lowering the performance of a software:
Speed (i.e. Response Time, data rendering and accessing) Capacity Stability Scalability Performance testing can be either qualitative or quantitative and can be divided into different sub-types such as Load testing and Stress testing.
It is a process of testing the behavior of a software by applying maximum load in terms of software accessing and manipulating large input data. It can be done at both normal and peak load conditions. This type of testing identifies the maximum capacity of software and its behavior at peak time.
Most of the time, load testing is performed with the help of automated tools such as Load Runner, AppLoader, IBM Rational Performance Tester, Apache JMeter, Silk Performer, Visual Studio Load Test, etc.
Virtual users (VUsers) are defined in the automated testing tool and the script is executed to verify the load testing for the software. The number of users can be increased or decreased concurrently or incrementally based upon the requirements.
Stress testing includes testing the behavior of a software under abnormal conditions. For example, it may include taking away some resources or applying a load beyond the actual load limit.
The aim of stress testing is to test the software by applying the load to the system and taking over the resources used by the software to identify the breaking point. This testing can be performed by testing different scenarios such as:
Shutdown or restart of network ports randomly Turning the database on or off Running different processes that consume resources such as CPU, memory, server, etc. Usability Testing Usability testing is a black-box technique and is used to identify any error(s) and improvements in the software by observing the users through their usage and operation.
According to Nielsen, usability can be defined in terms of five factors, i.e. efficiency of use, learn-ability, memory-ability, errors/safety, and satisfaction. According to him, the usability of a product will be good and the system is usable if it possesses the above factors.
Nigel Bevan and Macleod considered that usability is the quality requirement that can be measured as the outcome of interactions with a computer system. This requirement can be fulfilled and the end-user will be satisfied if the intended goals are achieved effectively with the use of proper resources.
Molich in 2000 stated that a user-friendly system should fulfill the following five goals, i.e., easy to Learn, easy to remember, efficient to use, satisfactory to use, and easy to understand.
In addition to the different definitions of usability, there are some standards and quality models and methods that define usability in the form of attributes and sub-attributes such as ISO-9126, ISO-9241-11, ISO-13407, and IEEE std.610.12, etc.
UI testing involves testing the Graphical User Interface of the Software. UI testing ensures that the GUI functions according to the requirements and tested in terms of color, alignment, size, and other properties.
On the other hand, usability testing ensures a good and user-friendly GUI that can be easily handled. UI testing can be considered as a sub-part of usability testing.
Security testing involves testing a software in order to identify any flaws and gaps from security and vulnerability point of view. Listed below are the main aspects that security testing should ensure:
Confidentiality Integrity Authentication Availability Authorization Non-repudiation Software is secure against known and unknown vulnerabilities Software data is secure Software is according to all security regulations Input checking and validation SQL insertion attacks Injection flaws Session management issues Cross-site scripting attacks Buffer overflows vulnerabilities Directory traversal attacks Portability Testing Portability testing includes testing a software with the aim to ensure its reusability and that it can be moved from another software as well. Following are the strategies that can be used for portability testing:
Transferring an installed software from one computer to another. Building executable (.exe) to run the software on different platforms. Portability testing can be considered as one of the sub-parts of system testing, as this testing type includes overall testing of a software with respect to its usage over different environments. Computer hardware, operating systems, and browsers are the major focus of portability testing. Some of the pre-conditions for portability testing are as follows:
Software should be designed and coded, keeping in mind the portability requirements. Unit testing has been performed on the associated components. Integration testing has been performed. Test environment has been established.
Vegeu Test Driven Development
Es necessita la extensió Xdebug i php-code-coverage ([2]):
$ composer require phpunit/php-code-coverage
$ phpunit --coverage-text=./coverage.txt PHPUnit 4.8.24 by Sebastian Bergmann and contributors. Warning: The Xdebug extension is not loaded No code coverage will be generated. ......................................... Time: 4.72 seconds, Memory: 28.00Mb OK (41 tests, 120 assertions)
El informe en format text té un format similar a:
$ cat coverage.txt Code Coverage Report: 2016-05-05 10:17:50 Summary: Classes: 67.44% (29/43) Methods: 77.42% (72/93) Lines: 73.33% (220/300) \App::Group Methods: 100.00% ( 3/ 3) Lines: 100.00% ( 3/ 3) \App::Notification Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 1/ 1) \App::User Methods: 66.67% ( 4/ 6) Lines: 71.43% ( 5/ 7) \App\Console::Kernel Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 1/ 1) \App\Events::UserHasRegistered Methods: 50.00% ( 1/ 2) Lines: 80.00% ( 4/ 5) \App\Exceptions::Handler Methods: 50.00% ( 1/ 2) Lines: 90.91% ( 10/ 11) \App\Http\Controllers::GroupsController Methods: 100.00% ( 8/ 8) Lines: 100.00% ( 28/ 28) \App\Http\Controllers::GroupsNotificationsController Methods: 75.00% ( 3/ 4) Lines: 93.33% ( 14/ 15) \App\Http\Controllers::GroupsUsersController
També tenim un format en XML anomenat Clover que és utilitzat per múltiples llenguatges de programació i sistemes de proves. Per configurar el report en format clover al fitxer phpunit.xml afegiu:
<logging> <!-- and this is where your report will be written --> <log type="coverage-clover" target="./clover.xml"/> </logging>
I suposem també que teniu algun apartat similar a:
<filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./app</directory> <exclude> <file>./app/Http/routes.php</file> </exclude> </whitelist> </filter>
IMPORTANT: El fitxer phpunit.xml de Laravel ja conté aquesta secció, només us cal afegir l'etiqueta XML logging
Ara al executar:
$ phpunit
Se us crearà un fitxer clover.xml a l'arrel del vostre projecte.
O també podeu executar:
$ phpunit --coverage-clover clover.xml
Recursos:
PHPStorm permet executar els tests unitaris de PHPUnit amb coverage. Vegeu:
https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/23
Vegeu Phpstorm#Testing i els articles sobre PHPUnit, PHPSpec, Behat i Codeception per tenir més informació sobre testing a PHP.
Vegeu Testing Laravel
Podeu veure un exemple de tests al paquet adminlte-laravel:
https://github.com/acacha/adminlte-laravel/blob/master/tests/AcachaAdminLTELaravelTest.php