Three Recommended Paid Software Testing Online Courses

Free online courses are nice, but some paid ones are just better at delivering value especially when instructors take a lot of care about building the best possible content they can provide to their audience. Free is always an option, but the problem with free is that we don’t necessarily have to give anything back in return for a service. We can do nothing and that’s okay. With paid courses however I find myself to be more motivated to take in everything I can. I focus more and I believe that helps me learn better.

Here are three recommended paid software testing courses I’ve taken recently, from which I’ve learned a great deal:

Advertisements

Basic API Testing with PHP’s HTTP Client Guzzle

I like writing test code in Ruby. It’s a preference; I feel I write easy-to-read and easy-to-maintain code in them than with using Java, the programming language I started with in learning to write automated checks. We use PHP in building apps though. So even if I can switch programming languages to work with, sometimes I think about how to replicate my existing test code with PHP, because maybe sometime in the future they’ll have an interest in doing what I do for themselves. If I know how to re-write my test code in a programming language they are familiar with then I can help them with that.

In today’s post, I’m sharing some notes about what I found working when building simple API tests with PHP’s HTTP client Guzzle.

To start with, we have to install necessary dependencies. One such way for PHP projects is through Composer, which we’ll have a composer.json file in the root directory. I have mine set up with the following:

{
     "require-dev": {
          "behat/behat": "2.5.5",
          "guzzlehttp/guzzle": "~6.0",
          "phpunit/phpunit": "^5.7"
     }
}

Using Guzzle in code, often in combination with Behat we’ll have something like this:

use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;

     class FeatureContext extends PHPUnit_Framework_TestCase implements Context, SnippetAcceptingContext
     {
         // test code here
     }

where test steps will become functions inside the FeatureContext class. Our API tests will live inside such functions.

Here’s an example of a GET request, where we can check if some content is displayed on a page:

/**
* @Given a sample GET API test
*/
public function aSampleGET()
{
     $client = new Client();
     $response = $client -> request('GET', 'page_URL');
     $contents = (string) $response -> getBody();
     $this -> assertContains($contents, 'content_to_check');
}

For making requests to a secure site, we’ll have to update the sample request method to:

request('GET', 'page_URL', ['verify' => 'cacert.pem']);

where cacert.pem is a certificate file in the project’s root directory. We can of course change the file location if we please.

Now here’s an example of a POST request, where we are submitting an information to a page and verifying the application’s behavior afterwards:

/**
* @Given a sample POST API test
*/
public function aSamplePOST()
{
     $client = new Client(['cookies' => true]);
     $response = $client -> request('POST', 'page_URL', ['form_params' => [
          'param_1' => 'value_1',
          'param_2' => 'value_2'
     ]]);
     $contents = (string) $response -> getBody();
     $this -> assertContains($contents, 'content_to_check');
}

This is a basic POST request. You may notice that I added a cookies parameter when initializing the Guzzle client this time. That’s because I wanted the same cookies in the initial request to be used in succeeding requests. We can remove that if we want to.

There’s a more tricky kind of POST request, something where we need to upload a certain file (often an image or a document) as a parameter to the request. We can do that by:

/**
* @Given a sample POST Multipart API test
*/
public function aSampleMultipartPOST()
{
     $client = new Client(['cookies' => true]);
     $response = $client -> request('POST', 'page_URL', ['multipart' => [
          [
               'name' => 'param_1',
               'contents' => 'value_1'
          ],
          [
               'name' => 'param_2_file',
               'contents' => fopen('file_location', 'r')
          ]
     ]]);
     $contents = (string) $response -> getBody();
     $this -> assertContains($contents, 'content_to_check');
}

and use whatever document/image we have in our machine. We just need to specify the correct location of the file we want to upload.

Lessons from Lucius Seneca’s “On The Shortness Of Life”

One interesting topic I’ve come across this year in a few podcasts I listen to is Stoicism. William Irvine introduced the school of thought in an episode of the Art of Manliness podcast and Ryan Holiday wrote a practical guide about it for entrepreneurs on The Tim Ferriss Show. It has practical applications in daily life, and because of that I’d like to eventually learn more about what to practice and its how’s and why’s. For now though, I thought that reading up on Seneca’s essay ‘On the Shortness of Life‘ would be a good starting point.

Here are some notes from the essay:

  • It’s not that we have a short time to live, but that we waste much of it. Life is long enough, and it’s been given to us in generous measure for accomplishing the greatest things, if the whole of it is well invested. But when life is squandered through soft and careless living, and when it’s spent on no worthwhile pursuit, death finally presses and we realize that the life which we didn’t notice passing has passed away. So it is: the life we are given isn’t short but we make it so; we’re not ill provided but we are wasteful of life.
  • Look at those whose prosperity draws crowds: they are choked by their own goods. How many have found their wealth a burden! How many are drained of their blood by their eloquence and their daily preoccupation with showing off their abilities! How many are sickly pale from their incessant pleasures! How many are left with no freedom from the multitude of their besieging clients!
  • What foolish obliviousness to our mortality to put off wise plans to our fiftieth and sixtieth year, and to want to begin life from a point that few have reached!
  • The person who devotes every second of his time to his own needs and who organizes each day as if it were a complete life neither longs for nor is afraid of the next day. For what new kind of pleasure is there that any hour can now bring? Everything has been experienced, everything enjoyed to the full. For the rest, fortune may make arrangements as it wishes; his life has already reached safety. Addition can be made to this life, but nothing taken away from it – and addition made in the way that a man who is already satisfied and full takes a portion of food which he doesn’t crave and yet has room for.
  • I am always astonished when I see people requesting the time of others and receiving a most accommodating response from those they approach. Both sides focus on the object of the request, and neither on time itself; it is requested as if it were nothing, granted as if it were nothing. People trifle with the most precious commodity of all; and it escapes their notice because it’s an immaterial thing that doesn’t appear to the eyes, and for that reason it’s valued very cheaply – or rather, it has practically no value at all.
  • The greatest waste of life lies in postponement: it robs us of each day in turn, and snatches away the present by promising the future. The greatest impediment to living is expectancy, which relies in tomorrow and wastes today. You map out what is in fortune’s hand but let slip what’s in your own hand. What are you aiming at? What’s your goal? All that’s to come lies in uncertainty: live right now.
  • There is a common saying that it was not in our power to choose the parents we were allotted, and that they were given to us by chance; yet we can be born to whomever we wish. There are households of the most distinguished intellects: choose the one into which you’d like to be adopted, and you’ll inherit not just the name but also the actual property, which is not to be hoarded in a miserly or mean spirit: the more people you share it with, the greater it will become.
  • Honors, monuments, all that ostentatious ambition has ordered by decree or erected in stone, are soon destroyed: there’s nothing that the long lapse of time doesn’t demolish and transform. But it cannot harm the works consecrated by wisdom: no age will efface them, no age reduce them at all. The next age and each one after that will only enhance the respect in which they are held, since envy focuses on what is close at hand, but we more freely admire things from a distance.
  • It is nevertheless better – believe me – to know the balance sheet of one’s own life than that of the public grain supply.
  • In this mode of life much that is worth studying awaits you: the love and practice of the virtues, forgetfulness of the passions, knowledge of how to live and to die, and deep repose.

Recognition

When you find out that what you’ve shared into the world, something you’ve poured your heart into, is not recognized by those who you thought will be thankful for it, it isn’t really worthwhile to antagonize them. You’re just crying over spilled milk. Sure, cry, but please ask why you made the thing in the first place and give yourself an honest answer. Why was the thing important? Is it truly for your audience or for yourself? Did they actually tell you to create the thing, or was it an initiative? Why aren’t you satisfied with what you’ve done? Was it a requirement that they use the thing you’ve built too? Is it necessary to be recognized? Isn’t it enough to know that you made something of value at least for yourself?

And if you’ve made the thing you did for consumption and it wasn’t consumed by the people you think would, maybe the thing isn’t as valuable as you think it is. Listen to your audience, to their comments, and, perhaps, to their silence. Understand their wants and needs. Talk to them. Maybe something significant is missing.

Everyday, Prepare Something To Be Curious For

Everyday, prepare a very specific question (or a task) interesting enough to warrant research for an answer within several hours without distraction. Sometimes for learning, sometimes for fun, hopefully most days for both. Everyday there must be an adventure to immerse in, albeit small, something to be curious for.

Building a Docker Image of Existing Test Code, with Dependencies Automatically Installed

When I first tried Docker a couple of years back, I did not find it much different from using a virtual machine. Perhaps because I was experimenting with it on Windows, or perhaps it was still a relatively new app back then. I remember not having a pleasant experience installing and running it on my machine, and at the time it was just easier to run and debug Selenium tests on a VM.

I tried again recently.

Building a Docker image containing test code with dependencies automatically installed, with Docker Toolbox on Windows 7

And I was both surprised and delighted to be able to build a Docker image with an existing test code and its dependencies automatically installed, right out of the box. This is very promising; I can now build development environments or tools which can run on any machine I own or for teams. To use them we just need install Docker and download the shared image. No more setup problems! Of course, there’s still a lot to test – we’ll probably want to have an image be slim in size, automatically update test code from a remote repository, among other cool things. I’ll try those next.

Here’s what the Dockerfile looks like:

FROM ruby:latest
RUN mkdir /usr/src/app
ADD . /usr/src/app/
WORKDIR /usr/src/app/
RUN gem install bundler
RUN bundle install

Short and easy to follow. Then we build the image by running the following command on the terminal (on the root project directory):

docker build -t [desired_image_name] .

To run and access the image as a container:

docker run -i -t [image_name]:[tag_name] /bin/bash

And from there we can run our cucumber tests inside the container the same way as we do on our local machine.

There Are Many Interesting Things I

There’s a lot of interesting things in the software development and testing space, lots of stuff to study and learn. The past few years I spent learning to build automated checks in Java and Ruby has been a fun ride and I’ve learned a great deal about the concepts, benefits, and pitfalls of automation. Now I’m at that point where I’m thinking of what other areas I’d like to study next. There’s JavaScript – which I’ve recently started educating myself how to use through freeCodeCamp’s ‘Beau teaches JavaScript’ playlist and James Shore’s ‘Let’s Code Test-Driven Javascript subscription course – because I can quickly write small tools with through the browser. After digesting the basics, I’ll likely spend more months understanding the TDD process and build something, hopefully becoming proficient in it before the year ends.

But there are some other intriguing experiments I’d like to try, some of which are:

Maybe you’d like to test them too. 🙂