{"id":1977,"date":"2016-04-12T09:50:48","date_gmt":"2016-04-12T09:50:48","guid":{"rendered":"https:\/\/intelligentbee.com\/blog\/?p=1977"},"modified":"2024-08-28T12:09:05","modified_gmt":"2024-08-28T12:09:05","slug":"start-writing-tests-in-ruby-useful-gems","status":"publish","type":"post","link":"https:\/\/intelligentbee.com\/blog\/start-writing-tests-in-ruby-useful-gems\/","title":{"rendered":"Start writing tests in Ruby: useful gems"},"content":{"rendered":"<p>Being a QA engineer is a continuous struggle in\u00a0finding the right resources in order to get the job done easier and more efficiently.\u00a0If you are planning to\u00a0write automated tests in RSpec (Ruby&#8217;s testing framework), then you should take a look over these gems. Please notice that I am most of the time automating backend tests only, so the libraries I am using are for this purpose mainly.<\/p>\n<p>&nbsp;<\/p>\n<h2>1. RestClient<\/h2>\n<p>&nbsp;<\/p>\n<p><code>gem install rest-client<\/code><\/p>\n<p>If you want to make API calls on RESTful endpoints this should definitely\u00a0be your choice. This library is easy to use and the response includes code, cookies, headers and body.<\/p>\n<p>Let me show you how to make some calls (GET, PUT, POST, DELETE):<\/p>\n<pre class=\"lang:ruby decode:true\">response = RestClient.get(url, header){|response, request, result | response}\r\nresponse = RestClient.put(url, payload, header){|response, request, result | response}\r\nresponse = RestClient.post(url, payload, header){|response, request, result | response}\r\nresponse = RestClient.delete(url, header){|response, request, result | response}\r\n<\/pre>\n<p>Now you simply use this response for your purposes (<em><strong>response.code<\/strong><\/em>, <em><strong>response.body<\/strong><\/em>, etc.).<\/p>\n<p>&nbsp;<\/p>\n<h3>2. JSON<\/h3>\n<p>&nbsp;<\/p>\n<p><code>gem install json<\/code><\/p>\n<p>If I told you about RestClient, then the next one\u00a0should be\u00a0<strong>json<\/strong>. RESTful services will return JSON format in body most of the times so you should parse that response to be easier to work with.<\/p>\n<pre class=\"lang:ruby decode:true\">response = RestClient.post(url, payload, header){|response, request, result | response}\r\nparsed_response = JSON.parse(response.body)\r\nexpect(parsed_response['errors'][0]['message']).to eq \"Not Found\"<\/pre>\n<p>See how simple this is? You only\u00a0<strong>JSON.parse<\/strong> that response and that&#8217;s all!<\/p>\n<p>Since we are talking about JSON, let me show you how to build one:<\/p>\n<pre class=\"lang:ruby decode:true \">payload_hash = {\r\n            :key1 =&gt; :value1,\r\n            :key2 =&gt; :value2\r\n        }\r\npayload_json = payload_hash.to_json<\/pre>\n<h3><\/h3>\n<p>&nbsp;<\/p>\n<h3>3. Nokogiri<\/h3>\n<p>&nbsp;<\/p>\n<p>JSON and XML are the most used formats in web development. So you probably guessed that now I will show you some tricks on how to use XML in your awesome tests.<\/p>\n<p><code>gem install nokogiri<\/code><\/p>\n<p>When I have installed this gem on my ubuntu (v14.04) virtual machine, I have had the following error:<\/p>\n<pre class=\"lang:scheme decode:true \">ERROR: Error installing nokogiri:\r\nERROR: Failed to build gem native extension.\r\n\r\n\/usr\/bin\/ruby1.9.1 extconf.rb\r\n\/usr\/lib\/ruby\/1.9.1\/rubygems\/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)\r\nfrom \/usr\/lib\/ruby\/1.9.1\/rubygems\/custom_require.rb:36:in `require'\r\nfrom extconf.rb:4:in `'<\/pre>\n<p>But this was quickly fixed after installing ruby-dev and\u00a0ruby1.9.1-dev:<\/p>\n<p><code>sudo apt-get install ruby-dev<br \/>\nsudo apt-get install ruby1.9.1-dev<\/code><\/p>\n<p>Now let&#8217;s say you have the following XML:<\/p>\n<pre class=\"lang:scheme decode:true \">&lt;Envelope xmlns=\"http:\/\/schemas.xmlsoap.org\/soap\/envelope\/\"&gt;\r\n    &lt;Body&gt;\r\n        &lt;Login&gt;\r\n            &lt;username&gt;username&lt;\/name&gt;\r\n            &lt;password&gt;secret_password&lt;\/password&gt;\r\n        &lt;\/Login&gt;\r\n    &lt;\/Body&gt;\r\n&lt;\/Envelope&gt;<\/pre>\n<p>If you want to access the values for\u00a0<strong>username<\/strong> and\u00a0<strong>password<\/strong>, simply do this:<\/p>\n<pre class=\"lang:ruby decode:true \">your_file = Nokogiri::XML(your_XML_file)\r\nyour_file.remove_namespaces!\r\nputs your_file.css('username').text\r\nputs your_file.css('password').text<\/pre>\n<p>Also, you can use\u00a0<strong>xpath<\/strong> instead of\u00a0<strong>css<\/strong>.<\/p>\n<p>Let me show you how to build the previous XML file using Nokogiri:<\/p>\n<pre class=\"lang:ruby decode:true\">builder = Nokogiri::XML::Builder.new do |xml|\r\n  xml.Envelope {\r\n    xml.Body {\r\n      xml.Login {\r\n        xml.username \"username\"\r\n        xml.password \"secret_password\"\r\n      }\r\n    }\r\n  }\r\nend\r\nputs builder.to_xml<\/pre>\n<h3><\/h3>\n<p>&nbsp;<\/p>\n<h3>4. Sinatra<\/h3>\n<p>&nbsp;<\/p>\n<p>This gem is used to mock endpoints. See more about it <a href=\"https:\/\/intelligentbee.com\/blog\/how-to-mock-endpoints-in-automated-acceptance-tests\/\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3>5. Dotenv<\/h3>\n<p>&nbsp;<\/p>\n<p><code>gem install dotenv<\/code><\/p>\n<p>It is recommended to keep environment variables and stuff like usernames, passwords and URLs in a\u00a0<strong>.env<\/strong> file. In order to load those variables in your tests, you must use this gem.<\/p>\n<pre class=\"lang:ruby decode:true \">Dotenv.load\r\n\r\nlogin_url = ENV['VAR_NAME']\r\nsignup_url = ENV['VAR_NAME']\r\n\r\n<\/pre>\n<p>First you load the <b>.env<\/b> file, then use those variables in your tests.<\/p>\n<p>&nbsp;<\/p>\n<h3>6. Mysql<\/h3>\n<p>&nbsp;<\/p>\n<p><code>gem install mysql<\/code><\/p>\n<p>The name itself says what this is used for. See below how to open a connection to a MySql database and do a simple operation:<\/p>\n<pre class=\"lang:ruby decode:true \">con = Mysql.new(db_host, db_user, db_pass, db_schema, db_port)\r\n\r\nrs = con.query(\"UPDATE table_references SET col_name1= ... WHERE where_condition\")\r\n\r\ncon.close<\/pre>\n<p>&nbsp;<\/p>\n<p>I will update this post when I will use some new\u00a0awesome Ruby library. What gems are you using?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Being a QA engineer is a continuous struggle in\u00a0finding the right resources in order to get the job done easier [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":3283,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73,84],"tags":[144,162,175,182,212,213,214,228],"yst_prominent_words":[593,1013,1236,2330],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1977"}],"collection":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/comments?post=1977"}],"version-history":[{"count":3,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1977\/revisions"}],"predecessor-version":[{"id":133190,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1977\/revisions\/133190"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media\/3283"}],"wp:attachment":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media?parent=1977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/categories?post=1977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/tags?post=1977"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}