Agile, test-driven development

Getters and Setters

For the constructor of the User class to accept the email string parameter as a named parameter, an eponymous accessor method to give it back, and a setter to set new values, Perl hackers had to insert dozens of lines of code manually in the pre-Moose era. With Moose, this is a no-brainer because its has function defines a class attribute that can, at the same time, be addressed using a constructor parameter, a getter – email() – and a setter – email( $ email ).

Listing 4 shows a later version of the User class that uses has to define the email attribute. Its is parameter uses rw to make the value readable and writable; isa defines it as a Str (i.e., an arbitrary string).

Listing 4


Running the test suite again in Figure 2 shows that all three defined test cases now complete successfully. So, development can proceed.

Figure 2: Green light: The test suite runs without error; agile development can now proceed.

Putting the Customers in a Database

The next thing the product development specification requires is that users register in a customer database using their email addresses. True to the principles of TDD, Listing 5 defines the first test case with the test_customers() routine. It uses the Customers class and its new() constructor to generate a new in-memory customer database.

Listing 5


Next, it feeds two new users with their email addresses to the database using the not yet existing sign_up() method. In the second for loop starting in line 19, the test routine uses ok and the method user_find_by_email() to check whether the customer file object can find the recently registered customers. In this case, the method will return a true value by definition, once it has been implemented.

Searching for Users

Again, all grinds to a halt if the failed test suite wants it to be that way. To fix the "bug," Listing 6 implements the Customers class, again using Moose and two additional methods. Perl's object system passes in a reference to the object as the first argument in method calls. The class defines a global hash %USERS in which the sign_up() method stores the User type object passed to it under the user's email address.

Listing 6


The lookup method user_find_by_email() calls exists to check the global hash and returns either the user object it finds, if the user is already registered, or undef if it does not find the user. Once the code in Listing 6 is free of errors, the green light comes on again, and a further milestone in the project is in the bag.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Perl: Regression Tests

    With a test suite, you can fix bugs and add new features without ruining the existing codebase.

  • Perl: Web Regression Test

    Testing complex web applications does not necessarily mean investing in expensive, proprietary tools such as Test Director or Silk Performer. Selenium is for free; it can remotely control any major browser, and it is programmable in Perl.

  • Perl: Cucumber

    The Cucumber test framework helps developers and product departments jointly formulate test cases, not as program code, but in plain English. The initially skeptical Perlmeister has acquired a taste for this.

  • Calculating Probability

    To tackle mathematical problems with conditional probabilities, math buffs rely on Bayes' formula or discrete distributions, generated by short Perl scripts.

  • Perl – Distro Update Analysis

    A Perl script calls various plugins that sniff around on FTP and HTTP servers run by the major Linux distributions to discover when Fedora, Debian, and other distros update their packages.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More