Is the test constructor too complicated?

Firstly, I will say that I came from the Java world (this is important, really).

I programmed PHP for a while, one of the problems that I encountered was that due to the lack of compilation, sometimes there are errors that can be easily detected during compilation (for example, the wrong number of parameters for this function) can silently pass .

This can be easily detected as the increase in code is increased by adding unit tests. The question is, does it make sense, for example, test constructors to verify the correctness of the passed parameters? I mean not only the number of parameters, but also the content of such parameters (for example, if the parameter is null, some objects must throw an exception to avoid creating a "dirty" object).

Question: am I too infected with years of Java code? Because, after all, increasing the reach of the code to “detect” missing functions looks like a (really) primitive way to compile.

In addition, I would like to note that I already use the development environment (PHPStorm), we also use tools such as PHPCodeSniffer.

Any ideas / suggestions?

+7
source share
3 answers

This is a good question that can be answered at several levels:

  • Language Characteristics
  • Testing
  • CASE Tools

1. Characteristics of the language As you noted, the characteristics of the PHP language are very different from more strongly typed languages ​​such as Java. This causes a serious problem when programmers coming out of more strongly typed languages ​​such as Java and C # may not be aware of the consequences of the behavior of PHP (for example, those described by you). This introduces the possibility of errors on the part of the programmer (for example, a programmer who may have been less careful using Java, because he knows that the compiler will catch the wrong parameters, may not correspond to the corresponding caution when developing in PHP). Therefore, to solve this problem, it is necessary to improve the education / control of programmers (for example, standards of internal coding of the company, pair programming, code review). It also (as you pointed out) raises the question of whether to increase test coverage in order to check for errors that would be caught by the compiler.

2. Coverage testing The argument for testing coverage is very specific to the project. In the real world, the level of test coverage is primarily dictated by the admission of a client error (which is dictated by the consequences of an error that occurs in your system). If you are developing software that should work in a real-time control system, then obviously you will test more. In your question, you define PHP as the language of choice; this may equally apply to the ever-increasing number of web interfaces for critical system infrastructure. On the other side of the coin, if you are developing a simple website for a model railway club and just developing a newsletter application, your client may not worry about the possibility of an error in the constructor.

3. CASE Tools Ultimately, it would be desirable for a CASE tool to be available that can detect these errors, such as missing parameters. If there are no suitable tools, why not create your own. Creating a CASE tool is not available to most programmers, especially if you can connect to the open source parsing engine for your language. If you are open source, this might be a good project to launch, or perhaps your company might sell such a solution.

Conclusion In your case, is it worth testing the designers, basically it comes down to the question: what will be the consequences of a failure in my system? If you have the point to spend additional resources testing your designers to avoid such crashes, you should do this. Otherwise, it may be possible to pass with less testing, such as pair programming or code reviews.

+4
source

Do you want the constructor to throw an exception if invalid parameters are set? Do you want to do the same tomorrow and next week and next year? Then you write a test to make sure it does.

Check that your code behaves the way you want it. Otherwise, the wrong parameters are code behavior, as well as calculating sales tax or displaying a user profile page.

+3
source

We test the constructors, as well as the order of the parameters, the default values ​​if they are not specified, and then some actual settings. For example:

class UTIL_CATEGORY_SCOPE extends UTIL_DEPARTMENT_SCOPE { function __construct($CategoryNo = NULL, $CategoryName = NULL) { parent::__construct(); // Do Not Pass fields to ensure that the array is checked when all fields are defined. $this->DeclareClassFields_(); $this->CategoryName = $CategoryName; $this->CategoryNo = $CategoryNo; } private function DeclareClassFields_() { $this->Fields['CategoryNo'] = new UTIL_ICAP_FIELD_PAIR_FIRST('CCL', 6, ML('Category'), 8); $this->Fields['CategoryName'] = new UTIL_ICAP_FIELD_PAIR_SECOND('CCL', 32, ML('Name'), 15, array(), array(), NULL, UTIL_ICAP_FIELD::EDIT_DENY, UTIL_ICAP_FIELD::UPDATE_DENY, 'DES'); } } 

Then we create our tests to not only check the constructor and its order, but this class and inheritance have not changed.

 public function testObjectCreation() { $CategoryInfo = new UTIL_CATEGORY_SCOPE(); $this->assertInstanceOf('UTIL_CATEGORY_SCOPE', $CategoryInfo); $this->assertInstanceOf('UTIL_DEPARTMENT_SCOPE', $CategoryInfo); $this->assertInstanceOf('UTIL_DATA_STRUCTURE', $CategoryInfo); // Inherited from UTIL_DEPARTMENT_SCOPE } public function testConstructFieldOrder() { $CategoryInfo = new UTIL_CATEGORY_SCOPE(1500, 'Category Name'); $this->assertEquals(1500, $CategoryInfo->CategoryNo); $this->assertEquals('Category Name', $CategoryInfo->CategoryName); } public function testConstructDefaults() { $CategoryInfo = new UTIL_CATEGORY_SCOPE(); $this->assertNull($CategoryInfo->CategoryNo); $this->assertNull($CategoryInfo->CategoryName); } public function testFieldsCreated() { $CategoryInfo = new UTIL_CATEGORY_SCOPE(); $this->assertArrayHasKey('CategoryNo', $CategoryInfo->Fields); $this->assertArrayHasKey('CategoryName', $CategoryInfo->Fields); $this->assertArrayHasKey('DeptNo', $CategoryInfo->Fields); // Inherited from Parent $this->assertArrayHasKey('DeptName', $CategoryInfo->Fields); // Inherited from Parent } 
+1
source

All Articles