Sardes Test Platform — Part I

Efe Girek
hepsiburadatech
Published in
5 min readMar 5, 2019

Ahoy Techblog,

Today I will try to explain some basic structure of the “RSpec” tool, which we choose for our API tests. RSpec is a testing tool for writing human readable specifications that direct and validate the development of your product. It designed for testing the business logic of your product, that means it basically tests the internal models and controllers.

Some of you may not know that tests also work as documentation, and the specs you write give other developers a quick entry point to learn a new code base and understand what it is supposed to do. Writing your code in RSpec is very expressive and forms highly readable blocks of code that tells your “user story”.

TDD/BDD

RSpec created for behavior-driven development (BDD), and to understand why RSpec is the way it is, we need to understand the point of BDD and its predecessor, test-driven development(TDD).

TDD is not really about testing, it is actually a design technique. It leads to a more cleaner code with separations of corner, and of course, cleaner code is more reliable and easier to maintain.

TDD’s main purpose is to create a loop of development that engages us, and it gives us lightweight work load by making development easy, and more goal oriented with clear specs.

The stages of TDD are commonly known as Red-Green-Refactor loop.

BDD is essentially the same as TDD, but it writes tests from a “user story” perspective, which helps solves a bunch of common software development problems.

Examples Groups

RSpec is a domain specific language(DSL) for creating executable examples of how code is expected to behave, organized in groups. It uses the words “describe” and “it” so we can express concepts like a conversation:

“Describe the money order api controller”

“It has a failed account summary”

These groups can be nested using the describe or context methods. A nested group is actually a subclass of the outer group, so it has access to same methods as the outer group.

RSpec allows us to define custom metadata for individual Examples or entire Example Groups. For example, you might focus your next test run on only those examples you are currently developing by using a “money” keyword:

To run only the examples tagged with money, use RSpec’s filtering configuration:

Matchers

RSpec comes with a nice collection of built in matchers, including:

Equality/Identity Matchers:

Matchers to test for object or value equality.

Comparison Matchers:

Matchers for comparing to values.

Class/Type Matchers:

Matchers for testing the type or class of objects.

Let and Before Blocks

RSpec has easy to use test data syntax, with a lazy-evaluated variables, and to create variables that are common across tests, the Ruby community prefers to use let, but before is often used to perform actions common across tests. Using let, the variable lazy loads only when it is used the first time in the test and get cached until that specific test is finished.

The beforeblock will run before each example, even if the example does not use any of the instance variables defined in the block.

Shared Examples

And finally, RSpec has a structure that favors Ruby mantra “don’t repeat yourself”(DRY), and if you want to successfully DRY up your code , you need to implement shared examples. When you have multiple specs that describe similar behavior, it might be better to extract unnecessary examples into shared examples and use them in multiple specs.

Apart from your it blocks, you can add let blocks, context, and describe blocks, which can also be defined inside shared examples. By extracting the shared tests into a single location, you can eliminate duplication and improve the consistency of your controller actions. This is very useful in case of designing API tests, as you can use the existing structure of RSpec.

Adding it_behaves_like "fails to save temp card" to your card controller, specs includes “fails to save temp card” block to your tests, then it executes the expectations against TrBank and EnBank by using the #it_behaves_like method:

I prefer to keep shared examples simple, and don’t add contexts and let blocks. The shared examples block also accepts parameters. Let’s say there are multiple fields that our API needs to validate, and that means there are multiple failed test scenarios that we need to write.

bank_examples.rb

By sending corrupted fields repetitively, you can use the same shared example in a single describe block.

bank_test_spec.rb

In the next part, I will mention more about our test environment, it has a rich arsenal in it consisting of various test gems(airborne, capybara, factory_bot, faker) and tools that are developed to ease automation.

--

--