Category Archives: ruby

Randomize your test data

Reading Time: 1 minute

TL;DR

This post is about one important testing method that should be automated, test data randomization.

You should randomize test data in automated script because this will make your automated test runs slightly more user likely because application that you are testing will be used by different users that will use different data inputs.

Also, it is very usual that application business rules are data driven. Based on data values, feature behaves differently. Using test data randomization, you can discover and test hidden business rules.

Here is my real example. I randomized account number, and soon realized that feature behaves non deterministic. One attribute output values were different from run to run. I could not define the rule.

I asked developers in dedicated slack channel about this behavior, and they explained that this is client business rule. Based on account first digit, created record was labeled differently (output attribute value). Of course, that business rule was not documented in any form.

In my ruby testing scripts, I use Faker gem. Happy test data randomization!

 

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Value of UI automation tests

Reading Time: 1 minute

TL;DR

After series of posts about How to kill UI regression testing, maybe you got impression that I am against UI browser automation test scripts. In this post, I will put my thoughts about the value of UI automation tests.

First some context. Here are requirements for excellent UI automation tests:

  • Language that enables you to write less code. Something like Ruby.
  • selenium web driver implementation in that language
  • framework just above selenium webdriver. For example watir-webdriver.
  • Page object pattern implementation
  • test framework, something like rspec. For writing awesome asserts.
  • gherkin implementation. Something like  cucumber. No, I have not changed my mind stated here. But we have different context here.
  • continuous integration tool. Something like jenkins
  • headless browser. Something like xvfb or sauce labs.

What is the value of UI automation test scripts? They represent executable documentation for your product. They help you to answer questions about complicated business scenarios. For example facebook  setting who can contact me.

Your testers will need to have a skill of writing DRY tests using those requirements. So when you have new tester on board, by reading those tests script, he can quickly learn application features.

Those tests would be run on jenkins and run should be triggered manually. Tests will provide you information is some automated feature changed. It is not wise to use those results for you regression testing strategy.

Because those checks, or asserts only check what is coded. Nothing else. And UI is for human users, not for test scripts. So human should always do smart regression testing , using its brain, eyes, ears and fingers.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How to prepare cucumber with tables in Ruby

Reading Time: 1 minute

TL;DR

In this post I will explain how to handle cucumber tables in the “Do not repeat yourself [source]” principle.

Data Tables are handy for passing a list of values to a step definition:

Given the following users exist:
 | name | email | twitter |
 | Aslak | aslak@cucumber.io | @aslak_hellesoy |
 | Julien | julien@cucumber.io | @jbpros |
 | Matt | matt@cucumber.io | @mattwynne |

Here is my first take how to index that data that was not DRY:

class UserListPage
 include PageObject
  data_map = {'name => 1, 'email' => 2, 'twitter' => 3}
  div(:name, :id => 'name')
  div(:email, :id => 'email')
  div(:twitter, :id => 'twitter')
end

And using that data_map in step definition:

Given /^the following users exist:$/ do |table|
data = table.raw[1]
data.shift
on UserListPage do |page|
  data.each {|row|
    expect(page.name).to eq row[page.data_map['name']]
    expect(page.email).to eq row[page.data_map['email']]
    expect(page.twitter).to eq row[page.data_map['twitter']]
  end
end

There is no need for data_map attribute, because table object already has this data. Dry version:

Given /^the following users exist:$/ do |table|
data = table.raw[1]
header = table.raw[0]
data.shift
on UserListPage do |page|
  data.each {|row|
    expect(page.name).to eq row[header.index('name')]
    expect(page.email).to eq row[header.index('email')]
    expect(page.twitter).to eq row[header.index('twitter')]
  end
end

And do not forget to remove data_map attribute from page object class.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How to automate check for youtube video subtitle

Reading Time: 1 minute

TL;DR

In this post I will explain how I implemented check that youtube video contains specific language subtitle.

As part of application acceptance test, I needed to implement UI check that confirms that selected youtube video contains selected subtitle language. Getting the value of youtube video available subtitles from youtube player would be hard (even not manageable) task. So I decided to use different approach.

I remembered that while “search videos by subtitle language” feature was developed, developers mentioned (in github issue conversation) that this feature will be based on youtube api. So why not use this same code in my automated check?

The risk is here that we are using api that could return different list of available subtitles than one that are obtained using youtube UI elements. But knowing that Google is very good at testing their product features, I labeled that risk as very low.

youtube video subtitles
youtube video subtitles

Here is cucumber step definition:

It is important to state that I found on this blog post how to get attribute value using watir-webdriver.

Always use your tools wisely. Do not force one way of achieving something if there is more elegant way.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How to get page_url value in ruby page-object gem

Reading Time: 1 minute

TL;DR

In this short post I will provide code example for undocumented page-object gem feature, how to get value of page object page_url attribute in page object instance.

If you do browser test automation, I advise you to use following software stack:

  • Ruby language
  • selenium-webdriver gem
  • watir-webdriver gem
  • page-object gem
  • cucumber

 

And most of your code base should be written in cucumber feature files, step definitions and page definitions using page-object framework. Doing that, your code base will be highly maintainable, readable and DRY.

All of mentioned frameworks are open sourced, and they do not document all of their features (although I am very satisfied with the documentation). Sometimes you need to dive in source code and spec tests of those frameworks.

Page object gem has a lot of useful helper methods at your disposal. page_url returns page url that is defined in class definition. For example:

But in page-object gem wiki page there is no example how to actually get page_url value.

To save your time browsing through gem code base, here is how you can do that:

 

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How to send shift and special characters in Selenium Webdriver with Ruby

Reading Time: 1 minute

TL;DR

In order to automate one browser scenario, I needed to send ampersand character. It seems that this is not an easy action in selenium webdriver. So, instead testing the web application, I spent some time in order to find out a hack how to send ampersand key to browser in programmatic way.

My first reaction was: Is this for real, selenium-driver ate ampersand character!? Google as helpful, I found following blog post how to resolve this issue. Solution is in Python, so I rewrote it in Ruby.

Conclusion

Instead of trying to find the solution how to automatically send ampersand in ruby to browser, instead I could do that “manually” and continue the real testing activity. So, my dear testers, when you hear developers claiming that they test their application, prove them wrong. They just try to find solutions how to use automation framework, and that has nothing with sapient activity, software testing!

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

How browser automation helped me to find UI issue

Reading Time: 1 minute
image credit: www.macforensicslab.com

TLDR

There is important misunderstanding that Context driven school of testing is against test automation and programming in general. In following example I will give an example that will help to refute such opinion.

Here is one context driven principle in action:

“Automated testing is not automatic manual testing: it’s nonsensical to talk about automated tests as if they were automated human testing.”

I am writing browser automation framework for one of my client. Web application is one page application with “heavy” javascript involvement. Framework contains script that does following:

Given that I sign in
When I open xy application tab
Then there is xy amount shown
And I log out.

I wrote that script with following mission, to check how javascript behaves in repetitive action.
After I ran script, I was not able to login to application. UI interaction is blocked, which is not unusual when you have javascript driven UI. Browser refresh action was shortcut to make application operational again.

I tried to reproduce the issue without the script, but without success. Difference between human actions and script actions were in timings. Log out step was done in script much faster. And that was cause of issue.

While application tab was still loading, script did log out action (interrupt), which cause unhandled exception in javascript.

This example supports context driven principle, that automated testing extends human testing, it does not replace it.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Two testers at Ruby::ZG::Meetup

Reading Time: 2 minutes

Yesterday, I attended Ruby Zagreb meet up. Officially, it

was first, but it was just first organized using Meetup platform. I think that Ruby group is one of the oldest meet up groups from Zagreb area. Meet up was held in club Mama. There is a story that in early days of Croatian Internet access (1992) Mama’s Internet fee for linux users was twice cheaper than for Windows users. 
We started with usual introductions. We had professional hard core Ruby developers, Ruby newcomers who wanted to find out why Ruby is such a great language, and two dedicated software testers.
Fun part started with Nikica’s presentation on Threads, Actors, Fibers and STM made easy with Celluloid framework. Presentation takeaway: serious concurrency is possible in plain Ruby.

Second presentation was held by Sime, how to create our own mini testing framework by reverse engineering minitest framework.

Presentation takeaway: by doing it, you will learn a lot of great stuff how to create your own framework. I was surprised that minitest was new in Ruby world, because I am from Java world. It seems that rspec was first Ruby testing framework, coming with its own DSL language and resolving some missing feature and obstacles in Junit framework (versions before number 3). I hope that there will not be future Ruby presentation how we switch back from minitest to rspec.

At the end, Vlado presented its own open source contribution with gem rails_db_info. Browse through your database tables in easy and effective way. Presentation takeaway: create it, encapsulate it, publish it as a gem, true meanings of open source. And, yes, you will learn something by doing it. Vlado learned how to configure Travis.
Zeljko announced Citcon unconference that will be held on 20. and 21. September in Zagreb. It is about continuous integration and testing that accompanies it. And it is FREE!
We continued mingling over beers at Kolding. I was part of interesting conversation about  ActiveRecord practical problems and challenges. I herd again that Rails is oversimplified and that “everybody” could start programming with it very quickly. That Rails is not framework for real projects. I can not argue against those arguments because I am not power Rails users, but again, coming from Java world (J2EEs and Spring frameworks), I think that Rails is very revolutionary framework. It is very testable (for example, I know few J2EE developers who would kill for Capybara J2EE framework) and security features are state of the art comparing to Java framework world.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Choose your testing tools using your brain

Reading Time: 2 minutes

For a tester, everything starts from its primary testing tool, its brain.
In my previous post I wrote about plsql-spec Ruby gem, my choice of weapon for testing Oracle technology. I started to test simple procedure that converts oracle DATE to character representation. For testing ideas I used this great post from test eye blog.
For a tester, time is very important source of testing ideas. Time was last added component to SFDPOT (mnemonic for San Francisco Depot) test strategy heuristic by James Bach.
I installed plsql-spec ruby gem on JRuby. JRuby uses Java as the underling virtual machine, while Ruby uses its own implementation written in C language. I used JRuby because my intention was to make testing infrastructure portable as much as possible. In order to connect to Oracle database, in JRuby you only need oracle jdbc driver, but pure Ruby requires Oracle Net Manager (which means for tester one more component to maintain) and oci8 gem.
My first testing session was to find the boundary of time supported in Oracle database.
Oracle Time range is [January 1, 4712 BC:December 31, 9999 AD].
Ruby Time class also supports BC years. For lower bound of supported Oracle DATE, just write:

plsql.bsn_eliste_pkg.to_tmstmp_tz( Time.local -4712, 1, 1 ,0, 0, 0 ).should eql “47120101000000 PNE”

where plsql procedure takes oracle DATE as input parameter. Python and Java lovers, parenthesis in Ruby are optional!
That code triggered following Java exception in JRuby:

Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
     # java.sql.Timestamp.valueOf(Timestamp.java:235)

I am not able to send BC dates to plsql procedure! When I switched back to pure Ruby, I got following test fail:

   Failure/Error: plsql.bsn_eliste_pkg.to_tmstmp_tz( Time.local -4712, 1, 1 ,0, 0, 0 ).should eql “47120101000000 PNE”

       
       expected: “47120101000000 PNE”
            got: “47120101000000”

In this case I revealed plsql procedure bug!
Lesson learned
Your primary tool is your brain. Using your brain, you learn about testing by reading smart blogs (like test eye). You want to implement Time test ideas for Oracle procedures. You found out about plsql-spec ruby gem. There is an option, JRuby or Ruby. If one option is blocking you in implementing your testing ideas (like JRuby in this case) try another option. Choose your testing tools using your brain!

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

PL/SQL unit testing with Jruby

Reading Time: 1 minute

In order to find out how to do unit testing of PL/SQL code, I found this great blog post by Raimonds Simanovskis. He created two Ruby gems, ruby-plsql and ruby-plsql-spec. Following instructions on github for plsql-spec gem, I installed gems, but for jruby platform.
There are other alternatives for doing unit testing of pl/sql code (Python is one of those and I have been using Python for years), but I decided to try Jruby implementation for three reasons:

  • Ruby language has better readability than Python (there, I said it). Its idioms are much comprehensible than Python language.
  • Rspec gem is better than Python unittest module.
  • Java jvm is better than Ruby virtual machine implementation
After creating plsql-spec project by initiating command

>plsql-spec init

I tried following example:

require “spec_helper”
describe “test installation” do
  it “should get SYSDATE” do
    plsql.sysdate.should_not == NULL
  end
end

In database.yml I used connection to Oracle database in my company.
I got following error:
Failing tests! 

and nothing more!
In order to investigate what is the problem, I directly run spec_helper.rb using jruby. After that invocation I received java exception:
java.sql.SQLDataException:  ORA-01882: timezone region not found
The solution was to enter following lines in spec_helper.py (that ruby script is generated by plsql-spec init)
ENV[‘TZ’] = ‘Europe/Zagreb’
after all require statements.
You should put your own time zone.

Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather