Testing modules in PHP. Basics of Unit testing in PHP using PHPUnit Unit tests php

Since throwing an exception in application code is a common occurrence, let's look at how this can be tested using PHPUnit.
In old articles on this topic you can find the use of the method setExpectedException(), but keep in mind that newer versions of phpUnit use the method expectException() to indicate the type of exception to expect.

The expectException() method, as well as the directive @expectedException are used in tests to indicate "expect such and such an exception". The test is considered passed if an exception of the specified type occurs.

Example.
An exception occurs if the passed parameter contains less than 4 characters:
class User ( public function verifyPassword(array $user)( if(strlen($user["password"])<4){ throw new LengthException("Количество символов в пароле (" .$user["password"]. ") не соответствует требованиям."); } // } }
Testing:
class UserTest extends TestCase ( public function testVerifyPassword() ( $obj = new User(); $user["password"] = "123"; $this->expectException(LengthException::class); $obj->verifyPassword($ user);
this code could be rewritten like this:
class UserTest extends TestCase ( /** * @expectedException LengthException */ public function testVerifyPassword() ( $obj = new User(); $user["password"] = "123"; $obj->verifyPassword($user); ) ) i.e. use the @expectedException directive specifying the desired exception.

IMPORTANT! Once PHPUnit catches the expected exception, this test method will stop executing!
In other words - if you have 2 or more tests in one method, for example:
$this->expectException(LengthException::class); $this->assertEquals(8, $result, "Two to the third power"); then when running the first test with an exception, the second will be skipped (provided that the exception is received). Therefore, you need to place exception tests in different methods
or:
- design try...catch blocks in the test method;

- use data provider.

Analysis of code coverage by tests. With a large number of classes, you may forget to test some methods or different versions of the results they return. You can also put something off for later or even suddenly decide to test something that you didn’t intend to do before. How can you quickly check what has already been tested and what has not?!! PHPUnit uses a tool for this:.

php-code-coverage To use, you must first connect the PHP extension Xdebug
in the php interpreter file - php.ini. IN OpenServer file php.ini
menu -> Advanced -> Configuration -> PHP
A configuration file will open where you need to uncomment the line (remove the semicolon in front):
;zend_extension="e:/openserver/modules/php/PHP-5.6/ext/php_xdebug.dll"
After making changes, do not forget to restart the server.

Check if the extension is connected, run the script with the command:
phpinfo();
or open the link http://127.0.0.1/openserver/phpinfo.php there must be a block "».

xdebug
Performance: phpunit --coverage-html tests\coverage here we indicate that the report should be provided as static html files

and place them in the coverage folder, which will appear in the tests directory. Opening the file index.html

from the coverage folder you can see a list of classes that were included in the report. When you click on the name of a class, a page with statistics for that class opens. Example: The red line highlights a fragment that was missed when creating tests. That is, in this case, you need to write a test in which this method
will return false.
If an error occurs when executing the command:
No whitelist configured, no code coverage will be generated then you need to change/create the phpunit.xml file in the project root and insert a block there
indicating the directory to be checked: app here we indicate that you need to check the code coverage with tests in php files from the catalog.

app The block is also used
to indicate directories and files that do not require scanning.

More details in the documentation. When working with Composer in command line To use, you must first connect the PHP extension, with php extension enabled
, a message may appear:
You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug

Which says that having the xdebug extension enabled has a significant impact on performance (decreases). Read how to solve this problem in my .

In the next article I will tell you how to work with simulating objects (mocks), which will complete the series of articles on the basics of using PHPUnit.

Do you guys do unit testing in PHP? I'm not sure I've ever done this...what is it?

assertEquals(0, count($stack));

array_push($stack, "foo");

I like to practice something called TDD using a unit testing system (in PHP, which is phpunit).

What I also really like about phpunit is that it also offers code coverage via xdebug. As you can see from the image below, my class has 100% testing coverage. This means that every line from my Authentication class has been verified, which gives me confidence that the code is doing what it's supposed to do. Keep in mind that coverage doesn't always mean your code is well tested. You can have 100% coverage without testing a single line of production code.

Netbeans

Personally, I like to test my code inside Netbeans (for PHP). with a simple mouse click (alt+f6) I can test all my code. This means I don't have to leave the IDE, which I really like, and helps save time switching between sessions.

This is the first part of the "PHPUnit for Beginners" series. In this guide, we will explain why to cover your code with unit tests and the full power of the PHPUnit tool. At the end we will write a simple test using PHPUnit.
  • PHPUnit for beginners. Part 1: Start using it.

Types of tests

Before we dive into PHPUnit, let's break it down Various types tests. Depending on how you want to categorize them, PHPUnit applies all types of software development tests.

Let's categorize tests based on their level of specificity. According to Wikipedia. In general, there are 4 recognized test levels:

  • Unit testing: This level tests the smallest unit of functionality.
  • From a developer's point of view, the developer's job is to ensure that the function being tested does exactly what it is designed to do. Thus, it must be minimally or completely independent of another function or class. It must be written in such a way that it is executed entirely in memory, i.e. it should not connect to the database, should not access the network or use the FS, etc. Unit testing should be as simple as possible. Integration Testing: This layer "connects" different units
  • code and tests whether their combinations work correctly. It is built on top of unit testing and is able to catch bugs that cannot be detected using unit testing, because Integration testing checks whether class A works with class B.: It is designed to reproduce the operation of scenarios in conditions close to combat. This, in turn, is built on top of integration testing. While integration testing ensures that different parts of the system work smoothly. System testing is responsible for making sure the system works as the user expects before sending it to the next level.
  • Acceptance testing: While the above tests are intended for developers at the development stage, acceptance testing is actually performed by users of the software. Users are not interested in the internal features of the software, they are only interested in how the software works.

If we put test types in a pyramid, it would look like this:

What is PHPUnit

Looking at the pyramid at the top, we can say that unit testing is the building block for all other types of testing. When we build a strong foundation, we are able to build a sustainable application. However, writing tests manually and running tests every time you make changes is a labor-intensive process. If there was a tool to automate this process, writing tests would become a much more enjoyable experience.

This is where PHPUnit comes into the picture. Currently, PHPUnit is the most popular unit testing framework in PHP. In addition to having features such as mocking objects, it can also analyze code coverage, logging, and provide thousands of other features.

Let's install PHPUnit on our system:

  1. Download it: PHPUnit is distributed in a PHAR(PHp ARhive) file. You can download it.
  2. Add its path to the $PATH system variable: after downloading the PHAR file, make sure that it is executable and the path where it is located is registered in the $PATH system variable. That. you can run it from anywhere.

If you are working on a Unix-like system, then you can do this with the following commands:

$ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ sudo mv phpunit.phar /usr/local/bin/phpunit

If you did everything correctly, you can see the version of PHPUnit installed by typing the command in your terminal:

$phpunit --version

Your first unit test

It's time to write your first unit test! First, we need some class that we will test. Let's write a simple class called Calculator. And let's write a test for it.

Create a file "Calculator.php" and copy the code below into it. This Calculator class has only one add method.

Class Calculator ( public function add($a, $b) ( return $a + $b; ) )

Now create a test file "CalculatorTest.php" and copy the following code into it. We will look at each method in more detail.

Require "Calculator.php"; class CalculatorTests extends PHPUnit_Framework_TestCase ( private $calculator; protected function setUp() ( $this->calculator = new Calculator(); ) protected function tearDown() ( $this->calculator = NULL; ) public function testAdd() ( $result = $this->calculator->add(1, 2); $this->assertEquals(3, $result) )

  • Line 2: connect the file of the tested class Calculator.php. Since this is the class we are going to test in this file, make sure it is included.
  • Line 8: setUp() is a method that is called before each test. Remember he called before each test, which means that if you add another test method to this class, it will be called before it too.
  • Line 13: Similar to the setUp() method, tearDown() is called after each test.
  • Line 18: testAdd() is a test method for the add() method. PHPUnit will recognize every method starting with test as a test method and run it automatically. This method is actually very simple: first we call the Calculator::add() method to calculate the value of 1 plus 2, and then we check that this method returned the correct value using assertEquals() from PHPUnit.

The final part of the work done is to run PHPUnit and check that all tests pass (run without errors). In your terminal, go to the directory where you created the test file and run the following command:

$phpunit CalculatorTest.php

If you did everything correctly, you should see something like this:

PHPUnit 3.7.32 by Sebastian Bergmann. . Time: 31ms, Memory: 2.25Mb OK (1 test, 1 assertion)

Conclusion

We have completed the first tutorial in the "PHPUnit for Beginners" series. In the next article we are going to show you how to use a Data Provider in your tests.

We hope this simple guide will help you in your development and help you get started using unit testing.

If you liked the translation on this topic, read us at

Good day to all! Today I would like to talk to you about what it is unit testing in PHP.

When writing even the most simple programs periodically you have to stop and refactor in order to understand whether the program is written correctly. A code refactoring in PHP I already talked about it in one of the publications on the site, which you can read.

In general, of course, this approach is not bad, but it has significant drawbacks. So, for example, when writing some fairly large project, the code will gradually become clogged with commented out debugging functions, such as print or print_r.In the case of working on your own project, the code of which no one, or almost no one, is going to read, it will, to some extent, be justified.

However, let's imagine this situation: You write websites for customers using your own content management system. Customers are happy, you feel great, but one day you realize that the system you have developed no longer meets the requirements for it, it needs changes. And you start rewriting one part of the system after another.

There comes a time when one new class, method, condition or cycle - destroy the entire system. Changes in one place lead to errors in another. And now they are already climbing endlessly, as if from a cornucopia, and it becomes clear that this is no longer possible. And everything would be much better if first, among other things, they had written PHP Unit tests. It’s not for nothing that Martin Fowler says, that whenever you try to print something through print for debugging or refactoring purposes, it's better to write it as Unit test.

So, we seem to have become familiar with the theory, now let’s move directly to the code. Important notes must be made here; all operations are carried out on a PC running Windows 7 with installed PHP 7 versions. Further it will be point by point.

2) Move the downloaded file to a folder C:\bin. Create a file in the same folder phpunit.bat, write the following contents into it: @php C:\bin\phpunit-6.3.0.phar %*

Please note that the path C:\bin must be defined in a system variable PATH, otherwise when you try to execute the command in the console phpunit You will get an error!

3) Open the console and run the command phpunit, and if everything is correct, then help should be displayed in the console.

Of course there are other ways PHPUnit installations however I found this method most acceptable. For additional information, you can always visit the official website of the project PHPUnit. So, the installation is complete, now let's move directly to the code.

// file StackTest.php, located in the directory C:/Projects/php/tests
// connect the main class TestCase from the PHPUnit\Framework namespace
use PHPUnit\Framework\TestCase;

// define the class under test as a descendant of the TestCase class
class StackTest extends TestCase
{
// the functions being tested are public and begin with the word test
public function testPushAndPop()
{
$stack = ; // created an array
// and checked the assert statement to ensure that the number of elements in the array is zero
$this->

$this->assertEquals("foo", array_pop($stack));
$this->assertEquals(0, count($stack));
}
}
?>

The code is well commented, but I’ll clarify a couple of points. cornerstone Unit testing is the statement ( assertion). An assertion is your assumption about the expected value, or in other words you assert that the value of a variable, an array element, the result of executing a method, etc. will be equal to such and such a value. In the example above, when the array is initially created, the expected value of its length is 0. This is actually the case in our example.

In this case we use only one statement assertEquals although in class TestCase libraries PHPUnit There are several dozen of them, for all occasions, so to speak.

So we wrote the test, what next? And then it needs to be launched. To do this, open the console, go to the folder with our test ( PHP Unit tests usually located in a separate folder tests) and run the command phpunit, passing it the current directory as an argument (indicated by a single dot).

cd C:/Projects/php/tests && phpunit .

This command will automatically go through all PHP tests, which are in this catalog. Once the execution is complete, it will output information about how many tests passed and possibly failed.

Thus, today we found out what is Unit testing in PHP that using it is not only useful, but also necessary. And if you know PHP bad, or don’t know it at all, then especially for you I have an excellent video course, in which, in particular, I discuss the topic in detail Unit testing in PHP.

This tutorial script in PHP shows how a test can be written as a single array of questions and answers. Since there can be several types of questions (choosing "yes" - "no", choosing one of several options, entering a number or string as an answer), we will need not just an array, but array of arrays, each element of which will describe everything that is needed to display and check the next question. These will be records with the following keys:

  • "q" - displayed question text;
  • "t" - question type corresponding to the desired HTML tag: "checkbox" for "yes/no" checkboxes, "text" for a string or number as an answer, "select" - for a list in which you need to select one value from several. We implement the selection of more than one value with the “multiselect” element we invented, which is a group of checkboxes processed together. In fact, a standard list "; foreach ($test as $key=>$val) ( error_check ($val); echo ($counter++). "; switch ($val["t"]) ( case "checkbox": echo $val ["q"]." "; break; case "text": $len = strlen ($val["a"]); echo $val["q"]." ".$item; echo " "; break; case "multiselect": $i = explode ("|",$val["i"]); echo $val["q"].": "; foreach ($i as $number=>$ item) echo $item."
    "; break; ) echo " "; ) function error_check ($q) ( $question_types = array ("checkbox", "text", "select", "multiselect"); $error = ""; if (!isset($q["q"] ) or empty($q["q"])) $error="There is no question text or it is empty"; else if (!isset($q["t"]) or empty($q["t"]) ) $error="Question type not specified or empty"; else if (!in_array($q["t"],$question_types)) $error="Invalid question type specified"; else if (!isset($q[ "a"]) or empty($q["a"]) and $q["a"]!="0") $error="There is no response text or it is empty"; else ( if ($q[" t"]=="checkbox" and !($q["a"]=="0" or $q["a"]=="1")) $error = "Responses 0 or 1 are allowed for the radio button" ; else if ($q["t"]=="select" || $q["t"]=="multiselect") ( if (!isset($q["i"]) or empty($q ["i"])) $error="No list elements specified"; else ( $i = explode ("|",$q["i"]); if (count($i)<2) $error="Нет хотя бы 2 элементов списка вариантов ответа с разделителем |"; foreach ($i as $s) if (strlen($s)<1) { $error = "Вариант ответа короче 1 символа"; break; } else { if ($q["t"]=="select" and !array_key_exists($q["a"],$i)) $error="Ответ не является номером элемента списка"; if ($q["t"]=="multiselect") { $a = explode ("|",$q["a"]); if (count($i)!=count($a)) $error="Число утверждений и ответов не совпадает"; foreach ($a as $s) if ($s!="0" and $s!="1") { $error = "Утверждение не отмечено как верное или неверное"; break; } } } } } } if (!empty($error)) { echo "

    Test error found: ".$error."

    Debug information:

    "; print_r ($q); exit; ) ) function strlwr_($s) yuya"; $len = strlen ($s); $d=""; for ( $i=0;<$len; $i++) { $c = substr($s,$i,1); $n = strpos($c,$hi); if ($n!==FALSE) $c = substr ($lo,$n,1); $d .= $c; } return $d; } ?>





2024 wisemotors.ru. How it works. Iron. Mining. Cryptocurrency.