module TestRailOperations

API's for Test Rail

Constants

BLOCKED
FAILED
PASSED
PENDING
RETEST
UNTESTED

Public Class Methods

add_test_case_to_test_plan(plan_id, entry_id, case_ids) click to toggle source

Updates a test plan with the given entry_id and array of test case IDSs

# File lib/files/testrail_operations.rb, line 228
def self.add_test_case_to_test_plan(plan_id, entry_id, case_ids)
  request = "update_plan_entry/#{plan_id}/#{entry_id}"
  data = {
      "suite_id" => self.suite_id,
      "case_ids" => case_ids
  }

  trclient = get_test_rail_client
  trclient.send_post_retry(request, data)
end
add_testcase_to_test_run(test_run_id, case_ids) click to toggle source
# File lib/files/testrail_operations.rb, line 271
def self.add_testcase_to_test_run(test_run_id, case_ids)
  request = "update_run/#{test_run_id}"
  data = { "case_ids" => case_ids }
  trclient = get_test_rail_client
  trclient.send_post_retry(request, data)
end
create_test_plan(name, description = 'created by api', entries = []) click to toggle source
# File lib/files/testrail_operations.rb, line 189
def self.create_test_plan(name, description = 'created by api', entries = [])
  request  = "add_plan/#{self.project_id}"
  data = {
      "name" => name,
      "description" => description,
      "entries"=> entries}
  get_test_rail_client.send_post(request, data)
end
create_test_plan_entry(plan_id, name, include_all_cases: true, case_ids: []) click to toggle source

Adds one test run to a test plan Returns hash containing:

  1. The test run ID of the test run.

  2. The entry ID of the test run which is a large Guid like this:

“id”=>“638fd46c-7c3e-4818-9c90-f411a2dec52a”

# File lib/files/testrail_operations.rb, line 209
def self.create_test_plan_entry(plan_id, name, include_all_cases: true, case_ids: [])
  if !include_all_cases && case_ids.count == 0
    return "Error! Must create a test plan with at least one test case"
  end

  request = "add_plan_entry/#{plan_id}"
  data = {
      "suite_id" => self.suite_id,
      "name" => name,
      "include_all" => include_all_cases,
      "case_ids" => case_ids
  }

  trclient = get_test_rail_client
  response = trclient.send_post_retry(request, data)
  { entry_id: response["id"], run_id: response["runs"][0]["id"] }
end
create_test_plan_entry_with_runs(plan_id, data) click to toggle source

new method to create plan entry with runs

# File lib/files/testrail_operations.rb, line 199
def self.create_test_plan_entry_with_runs(plan_id, data)
  request  = "add_plan_entry/#{plan_id}"
  get_test_rail_client.send_post(request, data)
end
create_test_run(project_id, suite_id, name, test_case_ids) click to toggle source

Creates a test run on testrail param project_ID - The integer identifier of the project on test rail. param suite_id - The integer identifier of the test suite on test rail. param name - The string name to call the new test run param test_case_ids - The array of numerical integers of test cases to add to the test run returns - The number ID of the test run.

# File lib/files/testrail_operations.rb, line 257
def self.create_test_run(project_id, suite_id, name, test_case_ids)
  request = "add_run/#{project_id}"
  data = {
    "suite_id" => suite_id,
    "name" => name,
    "include_all" => false,
    "case_ids" =>  test_case_ids
  }

  trclient = get_test_rail_client
  response = trclient.send_post_retry(request, data)
  response["id"]
end
delete_plan_entry(plan_id, days, force_delete = false) click to toggle source

For a given test plan deletes all runs equal to or older than the days passed Note that testrail stores runs as an entry and requires the entry id to remove the run To delete closer than 7 days, pass in force_delete = true

# File lib/files/testrail_operations.rb, line 309
def self.delete_plan_entry(plan_id, days, force_delete = false)
  if days >= 7 || force_delete == true
    clean_date = (Date.today - days).to_time.to_i
    trclient = get_test_rail_client
    request = "get_plan/#{plan_id}"
    response = trclient.send_get(request)
    response["entries"].each do |entry|
      if entry["runs"][0]["created_on"] <= clean_date
        uri = "delete_plan_entry/#{plan_id}/#{entry["id"]}"
        trclient.send_post_retry(uri, "")
      end
    end
  end
end
get_test_rail_cases(suite_id = nil) click to toggle source

Gets all the test cases for a particular test suite. The keys are the numeric(integer) test rail case ID's. The Values are the instance of TestCase. Each TestCase instance corresponds to a test case in test rail. return - A hash of TestCase instances

# File lib/files/testrail_operations.rb, line 109
def self.get_test_rail_cases(suite_id = nil)
  trclient        = get_test_rail_client
  screen_sizes    = get_test_rail_screen_size_codes
  priorities      = get_test_rail_priority_codes
  test_cases      = {}

  # retrieve test cases
  id_suite = suite_id ? suite_id : self.suite_id
  testcases_url = "get_cases/#{self.project_id}&suite_id=#{id_suite}"
  response = trclient.send_get(testcases_url)
  response.each do |test_case|
    id = test_case["id"]
    size = test_case["custom_screen_size"]
    screen_size_description = screen_sizes[size]
    priority = test_case["priority_id"]
    priority_description = priorities[priority]
    if priority_description
      priority_code = priority_description[:user_friendly_priority]
      automated = test_case["custom_automated"]
      run_once = test_case["custom_run_once"]
      automatable = test_case["custom_to_be_automated"]
      references = test_case["refs"]
      tc = TestCase.new(
        id.to_s, test_case["title"], priority_code, automated,
        screen_size_description, automatable, references, run_once
      )
      tc.file = test_case["custom_spec_location"]
      test_cases[id] = tc
    end
  end

  test_cases
end
get_test_rail_cases_for_all_suites(suite_ids) click to toggle source

Gets all the test cases for all the suites that we have for Bridge in Testrail suite_ids - An array of integers for each test suite under a testrail project

# File lib/files/testrail_operations.rb, line 145
def self.get_test_rail_cases_for_all_suites(suite_ids)
  result = {}
  suite_ids.each do |id|
    result.merge!(get_test_rail_cases(id))
  end
  result
end
get_test_rail_client() click to toggle source

Gets the Test Rail client docs.gurock.com/testrail-api2/bindings-ruby

# File lib/files/testrail_operations.rb, line 35
def self.get_test_rail_client
  url = ENV["TESTRAIL_URL"] || "https://canvas.testrail.com"
  trclient = TestRail::APIClient.new(url)
  trclient.user = ENV["TESTRAIL_USER"]
  trclient.password = ENV["TESTRAIL_PASSWORD"]
  trclient
end
get_test_rail_plan(plan_id) click to toggle source

Gets JSON data about an existing test plan docs.gurock.com/testrail-api2/reference-plans#get_plan

# File lib/files/testrail_operations.rb, line 183
def self.get_test_rail_plan(plan_id)
  trclient = get_test_rail_client
  request  = "get_plan/#{plan_id}"
  trclient.send_get(request)
end
get_test_rail_plans() click to toggle source

Returns a list of test plans for a project. docs.gurock.com/testrail-api2/reference-plans#get_plans

# File lib/files/testrail_operations.rb, line 175
def self.get_test_rail_plans
  trclient = get_test_rail_client
  request  = "get_plans/#{self.project_id}"
  trclient.send_get(request)
end
get_test_rail_priority_codes() click to toggle source

Gets the definition of the priority codes that are assigned to our test rail cases. The priority codes on testrail do not match our nice 1,2,3 numbers. Their codes are different from ours. i.e.

{1=>“3 - Low Priority”, 3=>“2 - Test If Time”, 4=>“1 - Must Test”, 6=>“Smoke Test”}

Therefore this function creates a more bridge friendly translation.

# File lib/files/testrail_operations.rb, line 78
def self.get_test_rail_priority_codes
  trclient = get_test_rail_client
  # retreive priority information
  # http://docs.gurock.com/testrail-api2/reference-priorities
  priority_response = trclient.send_get("get_priorities")

  results = {}
  priority_response.each do |priority|
    # find the numeric priority
    name = priority["name"]
    splits = name.split("-")
    key = priority["id"].to_i
    if splits.size == 2 && splits[0].to_i
      val = { name: name, user_friendly_priority: splits[0].to_i }
      results[key] = val
    elsif name == "Smoke Test"
      val = { name: "Smoke", user_friendly_priority: 0 }
      results[key] = val
    elsif name == "STUB"
      val = { name: "Stub", user_friendly_priority: 7 }
      results[key] = val
    end
  end
  results
end
get_test_rail_runs() click to toggle source

Gets JSON data about the test runs on testrail for the given project and suite

# File lib/files/testrail_operations.rb, line 167
def self.get_test_rail_runs
  trclient = get_test_rail_client
  request  = "get_runs/#{self.project_id}"
  trclient.send_get(request)
end
get_test_rail_screen_size_codes() click to toggle source

Gets the definition of device types that are assigned to our test rail cases. It looks like this: {1=>“Desktop”, 2=>“Tablet”, 3=>“Phone”}

# File lib/files/testrail_operations.rb, line 46
def self.get_test_rail_screen_size_codes
  trclient = get_test_rail_client
  case_fields = trclient.send_get("get_case_fields")

  results = {}
  case_fields.each do |case_field|
    if (case_field["name"] == "screen_size")
      config_array = case_field["configs"] # The array usually has a size of 1, but sometimes 0
      if config_array.size > 0
        config = config_array[0]
        # Some configs have items, like screen size
        items = config["options"]["items"]
        if items
          devices = items.split("\n")
          devices.each do |device|
            key, value = split_by_comma(device)
            results[key.to_i] = value
          end
        end
      end
    end
  end
  results
end
get_test_rail_user_by_email(email) click to toggle source

Given an email address, gets the user json data

# File lib/files/testrail_operations.rb, line 389
def self.get_test_rail_user_by_email(email)
  # The response looks like this:
  # {
  #    "email": "alexis@example.com",
  #    "id": 1,
  #    "is_active": true,
  #    "name": "Alexis Gonzalez"
  # }
  get_test_rail_client.send_get("get_user_by_email&email=#{email}")
end
get_test_rail_users() click to toggle source
# File lib/files/testrail_operations.rb, line 374
def self.get_test_rail_users
  # Returns an array of user hashes. Like this:
  # [
  # {
  #    "email": "alexis@example.com",
  #    "id": 1,
  #    "is_active": true,
  #    "name": "Alexis Gonzalez"
  # },
  # ....
  # ]
  get_test_rail_client.send_get("get_users")
end
get_test_run_cases(run_id) click to toggle source

When a test run is created, the test cases have new, sort of temporary ID's. These are completely different from the permanent static ID's of the test cases. Given a test run ID, this gets the test cases that are assigned to that test run. It returns a hash where the key is the integer permanent ID, and the value is a TestCase instance.

# File lib/files/testrail_operations.rb, line 328
def self.get_test_run_cases(run_id)
  result = {}
  trclient = get_test_rail_client
  response = trclient.send_get("get_tests/#{run_id}")
  response.each do |r|
    # Each response hash for a test case in a run looks like this:
    #
    # {"id"=>481664, "case_id"=>152222, "status_id"=>5, "assignedto_id"=>49, "run_id"=>2641,
    # "title"=>"The my Learning page has all my courses listed. Overdue, Next Up, Optional,
    # Completed", "type_id"=>2, "priority_id"=>3, "estimate"=>nil, "estimate_forecast"=>nil,
    # "refs"=>nil, "milestone_id"=>nil, "custom_sprint_date"=>nil, "custom_commit_url"=>nil,
    # "custom_reviewed"=>false, "custom_automated"=>true,
    # "custom_spec_location"=>"regression_spec/learner_management/mylearning_spec.rb",
    # "custom_test_order"=>nil, "custom_screen_size"=>3, "custom_preconds"=>nil,
    # "custom_steps_separated"=>nil, "custom_browser_skip"=>[]}
    #

    permanent_id = r["case_id"].to_i
    tc = TestCase.new(
      permanent_id, r["title"], r["priority_id"].to_i,
      r["custom_automated"], r["custom_screen_size"].to_i,
      r["custom_to_be_automated"], r["refs"], r["custom_run_once"]
    )
    tc.temp_id = r["id"].to_i
    tc.assigned_to = r["assignedto_id"].to_i
    tc.set_status(status_testrail_to_rspec(r["status_id"].to_i), nil)

    value = tc
    key = permanent_id
    result[key] = value
  end
  result
end
get_test_run_name(run_id) click to toggle source

Gets the string name of the test run, given the test run id as an integer if the test id is not found, it returns an empty string

# File lib/files/testrail_operations.rb, line 364
def self.get_test_run_name(run_id)
  runs = get_test_rail_runs(self.project_id)
  runs.each do |run|
    if run_id == run["id"].to_i
      return run["name"]
    end
  end
  ""
end
keep_only(plan_id, entry_id, case_ids) click to toggle source
# File lib/files/testrail_operations.rb, line 239
def self.keep_only(plan_id, entry_id, case_ids)
  request = "update_plan_entry/#{plan_id}/#{entry_id}"
  data = {
      "suite_id" => self.suite_id,
      "include_all" => false,
      "case_ids" => case_ids
  }

  trclient = get_test_rail_client
  trclient.send_post_retry(request, data)
end
post_run_results(run_id, data) click to toggle source

Sends test result data back to testrail to update cases in a test run param run_id - integer value designating the test run to update param data - A hash containing an array of hashes with test results

# File lib/files/testrail_operations.rb, line 300
def self.post_run_results(run_id, data)
  trclient = get_test_rail_client
  uri = "add_results/#{run_id}"
  trclient.send_post_retry(uri, "results" => data)
end
project_id() click to toggle source
# File lib/files/testrail_operations.rb, line 17
def self.project_id
  @@testrail_project_id
end
set_testrail_ids(pid, sid) click to toggle source
# File lib/files/testrail_operations.rb, line 12
def self.set_testrail_ids(pid, sid)
  @@testrail_project_id = pid
  @@testrail_suite_id = sid
end
split_by_comma(device_string) click to toggle source

Splits a string by a command and returns an array.

# File lib/files/testrail_operations.rb, line 26
def self.split_by_comma(device_string)
  splits = device_string.split(",")
  key = splits[0].chomp
  val = splits[1].lstrip
  [key, val]
end
status_rspec_to_testrail(result_symbol) click to toggle source

Converts an rspec test result (a symbol) to an integer that TestRail understands.

# File lib/files/testrail_operations.rb, line 288
def self.status_rspec_to_testrail(result_symbol)
  @rspec_to_testrail_status_map[result_symbol]
end
status_testrail_to_rspec(int_id) click to toggle source

Converts the a TestRail integer result status into a symbol (that rspec uses) that is human readable

# File lib/files/testrail_operations.rb, line 293
def self.status_testrail_to_rspec(int_id)
  @rspec_to_testrail_status_map.key(int_id)
end
suite_id() click to toggle source
# File lib/files/testrail_operations.rb, line 21
def self.suite_id
  @@testrail_suite_id
end
update_references(testrail_id, reference) click to toggle source

Updates a testcase that corresponds to the provided testrail_id. The testcase's reference field will be linked to the provided Jira ticket, given in the format of PROJECT-ID (ex. “BR-1000”) param - testrail_id. The integer ID of the testcase param - reference. The string of the JIRA ticket(s)

# File lib/files/testrail_operations.rb, line 159
def self.update_references(testrail_id, reference)
  puts "id: #{testrail_id} => refs: #{reference}"
  url = "update_case/#{testrail_id}"
  data = { "refs" => reference }
  TestRailOperations.get_test_rail_client.send_post_retry(url, data)
end