Recently, I have been tasked to create an automated content creator for end to end testing. This project should be able to create a drupal content type AND show the steps on how it is done properly. We could say that our team wanted to replicate a user workflow, automatically.The first thing that came to mind was Selenium, mainly because of how “visually verbose” the automation is when it comes to end to end testing. The only snag I ran into was that I decided to use PHP to conform with the products standards. PHPunit provides a great API library that allows functional testing and ties in with selenium well. However, it came to a point where I peered at my code and realized that the code isn’t readable and easy to understand at all. I lost all forms of sense and have been looking at blurbs of code that when given a week without looking at the code, I would lose all understanding of it. This is where I decided to encapsulate the data and methods to maintain sanity for myself and for the next developer coming along.

Traditionally, PHP has been branded as a “bad” kind of object oriented programming language. A lot of developers would shun the idea that PHP would be the best solution for a problem that requires object oriented principles. Although this may be the case, there is still sufficient reason to use data encapsulation to methodically control the native phpunit methods.

I’ve been asked countless times by my peers, “Why would you encapsulate method after method when you can just call that directly? It would be a double effort in doing the same thing”. The motivation is simple, make it so that when you present your code to someone else, that they know what you are doing. It could be a developer, who reviews your code before pushing upstream. It could be a 2nd QA engineer, who basically takes over that aspect of testing. The inspiration for this comes from black box testing, where you don’t necessarily need to know what is going inside the box, all you need to know is that it works properly, and this is what I am trying to achieve.

Encapsulating PHPunit methods were done with future developers on our minds.

Application

Essentially, I realized that using the PHPunit methods required only a few steps for the simple stuff, but more complex methods require some setup and navigation, which results in more code redundancy. Worrying about “clean” implementation for later, I started hashing out methods that encapsulated data being passed in and making it do the necessary steps to achieve a certain function.

Take sending text to an iframe field as an example. It has always been an issue for selenium to get text to parse correctly on iframes. For our project, our content editors use a ckeditor iframe. Considering that the project has multiple iframes, this would increase the number of code blocks necessary to achieve one particular function. A seasoned developer would have no problem handling this, but what if the next person in line was someone who only has basic knowledge of coding? Driven by this mindset, the solution that I came up with was:

public function frame_new($selector, $value){
    $framer = $this->byXpath($selector);
    $this->frame($framer);
    $this->byCssSelector('.cke_editable')->value($value);
    $this->frame(NULL);
  }

In essence, this method selects the frame for you, identifies the text field you want to send the text to, assigns the text to it, and reassigns the frame back to the parent. This code block is something that we can black box. No one needs to know how it’s done. As one of my coworkers says, it’s “magic”.

We also aimed to reduce more technical things to make the quality of life for the next person as simple as it can be. Insertion of local file paths in an exposed text field can be hard as there is no way to identify if the parsed string quantifies as a correct path until the end. For this project, we standardized all file paths being used in the projects in a folder called ‘assets’ and essentially, “baked” the file to spit out a correct string that would not be rejected (unless your file does not exist) by the selenium driver.

public function bake_file($filename){
    return dirname(__DIR__).'/event_creation/assets'.$filename;
  }

Again, these are the technical things that can be black boxed for your project so that when transitioning across developers and QA engineers, there is minimal to no chance that things will get lost in translation.

Now, the beauty of all of this is that you can look at the code and identify at first glance what the method is doing. With the same mindset, you can take this piece of code out into the world and let someone with little technical experience look at it, and see if they’d understand what is going on.

helper::field($title, ‘This is a page’, 'id');
  helper::field($eventLocation, ‘This is home’, 'id');
  helper::select($eventAddress, ‘This is where i found home’, 'id');
  helper::human_wait();
  helper::field($eventAddressCompany, ‘Contractor company’, 'name');
  helper::field($eventAddressStreet1, ‘31 Imaginary Street’, 'name');
  helper::field($eventAddressStreet2, ‘blank’, 'name');
  helper::field($eventAddressCity, ‘Magination’’, 'name');
  helper::select($eventAddressState, ‘Rhode Island’, 'name');
  helper::field($eventAddressZip, ‘12345’, 'name');
  helper::field($dateTextInput, ‘Feb. 29, 2016’, 'id');

As QA engineer with programming background, I wanted to be proactively helpful to our company and to the QA world by simplifying the amount of understanding the next person in line has to do. The less time he/she spends trying to figure out how to do things, the more time is being put into the quality of the project. There is no reason that people should be afraid of QA automation. In fact, automation takes the stress away from the QA engineer by simply just running one line of code. For people new to the field of QA, and in turn, programming; there shouldn’t be a reason why they should be intimidated by tasks that are complex and tedious if they have something to guide their way. This is what I am trying to achieve. Hopefully, we can transition code from person to person without the fear of losing data in the process.