Book Image

Selenium Design Patterns and Best Practices

By : Dima Kovalenko
Book Image

Selenium Design Patterns and Best Practices

By: Dima Kovalenko

Overview of this book

Table of Contents (18 chapters)
Selenium Design Patterns and Best Practices
Credits
Foreword
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
Index

Understanding test class naming


Unlike Java- or C-based programming languages, Ruby does not require the filename of a class to match the class contained inside. For example, the filename test1.rb can contain a class named Potato. Furthermore, a single file can contain multiple classes within it and Ruby compiler will not complain about it. With this setup, it is very easy to loose track of different pieces of code and classes. To reduce the complexity and confusion, there are several basic rules we can follow.

Note

Technically, these rules are more like suggestions, since the compiler will not prevent you from breaking them. Following them is advised, but not 100 percent necessary.

Naming files

It is a good idea to name the files as similar to the class that lives within it as possible. Since different test frameworks use different file naming conventions, we will adhere to the convention while at the same time clearly explaining what is contained inside the file.

For example, if we have a test that does a search for the word cheese on our website, we can name the file test_cheese_finder.rb or test_cheese_search.rb. Both examples clearly explain the intention of the test. We can still name the file test_curd_finder.rb, since it is both accepted by the compiler and expresses the intent of the test; however, not too many people will be able to find it when looking at a directory full of test files.

Tip

Since most Ruby developers do not use an IDE, there are some common practices, such as the one described previously, to make the development simpler to accomplish.

Naming classes

Similar to naming the files, naming the test class should be done in such a way that a test failure could be understood at a quick glance. For example, in Chapter 1, Writing the First Test, we have an intentional test failure that looks like this:

By looking at the failure message, we can identify the original intention of the test by the following three clues:

  • The filename of the failure tells us that the tests contained inside will be testing the ability to find cheese on our website, as shown in the following screenshot:

  • The class name, shown with an arrow in the following screenshot, reinforces the idea conveyed by the filename:

  • The test method name in the following screenshot shows that this particular test was testing the positive search result. If we wanted to test for negative search results, we would have named it test_cannot_find_cheese.

Understanding the namespace

Namespacing is a way of grouping logically related code together. Ruby modules are a great way to accomplish this, because they allow the declaration of classes within them. This allows us to have multiple classes with the same name within the same application without having a collision. It is similar to having two files with the same name in different directions.

When writing out the path to a class, Ruby uses the :: characters as a delimiter. For example, in Chapter 1, Writing the First Test, we are introduced to the Test::Unit framework for writing tests. All of the test classes inherit their behavior from the TestCase class in this framework. When the path to TestCase is fully written out, it looks like Test::Unit::TestCase. This statement gives us the following information:

  • The TestCase class lives inside of the Unit module

  • The Unit module lives within the Test namespace

Namespacing is a great way to sort our code in such a way that we can understand the intention of an object at a glance. It is similar to sorting the music collection by genre.

Showing object inheritance

The Test::Unit framework provides us with many great shortcuts when testing. For example, when we want to compare two numbers with each other and make sure they are equal, we can write our own comparison or we can use the assert method to do a comparison and display a meaningful failure message. Since we do not wish to write out every comparison by hand, we want our test class to inherit this behavior from the testing framework.

Note

For more information about objects, object-oriented programming, and inheritance, read Chapter 7, The Page Objects Pattern.

In Ruby, we declare object inheritance with the < character. This character shows the direction in which the inheritance is flowing; the < character shows the direction of inheritance, like an arrow. In the following test class declaration, we know that the CheeseFinderTest class will inherit all of its functionality from the TestCase class.

class CheeseFinderTests < Test::Unit::TestCase