Procedural Code Testing

90% of our code is linear in nature. In some places we have functions, but our code looks something like this:

<?php // gather some data // do something with that data // instantiate a bunch of globals // output a bunch of stuff to the browser include_once "file.php"; // output some more stuff include_once "file2.php"; // ad nauseum 

then in file.php

 <?php // do something with the globals from above // gather some more data // do something with this newfound data // output more stuff to the browser 

As part of moving to a cleaner code base, I want to start testing this, but I'm not sure how to do it right. Any suggestions? I do not understand how to do it right.

+4
source share
6 answers

As others commented, you essentially wrote procedural code. This type of code is generally not very suitable for unit testing or test-based development. To begin with, you should probably familiarize yourself with object-oriented programming and start grouping related pieces of functionality into appropriate abstractions.

You can try to find Link Seams and other similar tricks, but you are likely to fall into the world of pain if you do not begin to change the paradigm. If you cannot break your procedural PHP into small enough files with installed input and output points, which you can test separately. But this will definitely require creating methods and eliminating as many GLOBALS as possible.

The first thing you need to do is probably read Michael Faires Chapter 19 Working Effectively with Outdated Code . In fact, read the entire book. Since the โ€œseemingly simple bitโ€ of adding tests will require a paradigm shift.

+4
source

Third-party coders, Although I agree with the use of Selenium and the like ... I would like to point out this: We are talking about TDD. In my humble experience, TDD is what you catch like the flu. First, object-oriented programming must be understood, then unit testing must be studied.

I will call unit-testing: "test after" ... while the test after is a little stupid in terms of design, it will help you find out that you should switch from unit testing to the side, to unit testing, as the center of your object -oriented analysis and design.

At this point, you will begin TDD.

I am sad to say this, but if you are not a phenomenally loyal person, I believe that you look at a couple of years to understand all this ... and I am generous.

Please do not interpret this as insignificant for your character, nor a skill ... but working as a programmer (paying your bills with source code) and gaining mastery is not easy, as he sometimes faces business goals.

In short, depending on the business model of your organization, you may or may not be given sufficient planning. But you have to click.

Do not be afraid, because thanks to perseverance, you will one day be able to explain this to the youngest guy or lady trying to enter TDD.

Happy coding.

+1
source

Extract method and Extract class for refactoring. Comments are tips that tell you how to name these methods / classes.

For test platforms see http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#PHP

0
source

TDD means that tests come first. You do not need to test the existing code, you need to test the new one. This is unit testing after all - it checks a piece of code, not a whole page. To make sure that everything works the same as before refactoring, you need to write another type of test - functional. Basically emulate HTTP requests and check responses. Such tests can be built, for example, with selenium, and some PHP frameworks, such as symfony, provide their own server-side testing infrastructure for this.

0
source

I do not envy you. I was where you are (and still there!), And this is a bad place. Apart from a complete rewrite of your code base, this will not be an easy way. Ideally, you need to reorganize to check your code, but ideally you should check your code before refactoring. Catch 22. If you have a function, you can pass the test using one of the available framework tests (the testing framework does not work only with OO code!). Another strategy you could use would be to get a bit of your code under testing using web testing (using something like Selenium ). You can at least get your code in some kind of test harness to give some certainty, as you are reorganizing the code into something more verifiable.

0
source

Getting the procedural code under test is a nightmare, but a gradual approach is possible. Consider this:

 // bar.php $priceWithoutTax = 10; $priceWithTax = 10 * $annoyingGlobalVarWithTaxRateInIt; echo $priceWithTax; 

You must aim in the first case to achieve:

 //bar.php echo Foo::getPriceWithTax($annoyingGlobalVarWithTaxRateInIt); //Foo.php class Foo { public static function getPriceWithTax($annoyingGlobalVarWithTaxRateInIt) { $priceWithoutTax = 10; $priceWithTax = 10 * $annoyingGlobalVarWithTaxRateInIt; return $priceWithTax; } } //FooTest.php public function testGetPriceWithTax() { $expectedResult = 12; $taxRate = 1.2; $this->assertEquals($expectedResult, Foo::getPriceWithTax($taxRate)); } 

Perhaps this is not the way you want the code to end, but sticking the main part of the code in a static function, at least, allowed us to get real business logic (here a trivial calculation) under testing.

The goal of this, assuming that your code sometimes does something more complex than multiplying things by 10, is to enable safe refactoring. Now you can make changes to the implementation of the calculation (which for a more complex business logic than this should probably include the correct orientation of the object ;-)), safely knowing that your tests will tell you that you are something broke.

In general, you will always strive for a gradual approach to the application of unit tests and refactoring. Get the part of your code to such an extent that it can be tested with the smallest possible changes in the production code, then get it under control, then do more extensive refactoring for the part you are working on, then go to the next bit.

Good luck.

0
source

Source: https://habr.com/ru/post/1386142/


All Articles