こんにちは。おすしです。
■前回記事
今回はTestRailとmablの自動テストを連携したお話です。
連携方法やテストコードは下の方で全部公開しています。
※今回はmablのJenkinsプラグイン以外を使用していません。mablには便利なCLIがあるので、一度目を通しておくことをお勧めします。
自分の環境に合ったより良い連携方法をひらめくかもしれません。
mabl CLIの概要
https://help.mabl.com/docs/mabl-cli%E3%81%AE%E6%A6%82%E8%A6%81
連携図
自動化した内容
- Jenkinsからmablにテスト実行指令を出す。
- テストが完了すると、JenkinsのログからTestRailにテスト結果を記入する。
- 失敗したテストはGithubにissueを作成する。
- 失敗したテストはTestRailの結果に失敗時のスクリーンショットを添付し、「欠陥」にissueへのリンクを設定する。
連携手順①GithubとTestRailの設定
こちらの手順は前回の記事をご覧ください。
TestRailと自動テストの連携#1 Selenium/Python編
https://sqripts.com/2022/06/21/20407/
連携手順②mablの設定
APIキーを作成する
- メニューバーの「Setting(ワークスペース)」を押す
- 「APIS(API)」を押す
- 「API keys(APIキー)」を作成します※
- キーをコピーしておきます(Jenkinsの設定で使用します)
※ワークスペースの所有者レベルのユーザーのみがAPIキーを作成できます。使用しているアカウントに権限がなく、ワークスペースに使用できるAPI keyがない場合は、所有者に連絡をしてください。
mablでテストを作成する
こちらのページを使用させていただきました。
- マイヤーズの三角形問題:http://milk0824.sakura.ne.jp/services/myers/
- 動作確認環境
- Python 3.10.2
- requests 2.27.1
- Jenkins 2.332.2
まずは、mablのレコーディング機能を利用してテストをいくつか作成しておきます。
期待結果を編集して失敗するテストも準備します。
今回のJenkinsのログからテスト結果を取得する連携では、mablテスト名を利用して結果の記入処理を行います。
そのため、各テストは重複しない一意の名称にする必要があります。
連携手順③TestRailにインポートするテストデータを作成する
mablで作成したテストをTestRailにインポートするためのCSVファイルを作成します。
例:
No | A | B | C | result | objectives | testID |
---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 正三角形 | 正三角形のテスト1 | 13562 |
2 | 10 | 10 | 5 | 二等辺三角形 | 二等辺三角形のテスト(ABが等しい) | 13563 |
3 | 10 | 5 | 10 | 失敗するテスト | 失敗する三角形のテスト | 13564 |
4 | 1 | 1 | 1 | 正三角形 | 正三角形のテスト2 | 13565 |
5 | 1 | 1 | 1 | 正三角形 | 正三角形のテスト3 | 13566 |
6 | 1 | 1 | 1 | 正三角形 | 正三角形のテスト4 | 13567 |
各カラムの内容は
- No:テスト番号
- A,B,C:各辺に入れる値。
- result:「表示」ボタンを押した後の期待結果
- objectives:テストの目的。ここをmablのテスト名と完全に一致させます。
- testID:TestRailのテストID。インポート後に記入します
このCSVファイルをTestRailにインポートしてテストを作成します。
インポート後、CSVファイルの「testID」にテストIDを記入します。
連携手順④Jenkinsの設定
※インストールとユーザの作成までは、ほかのサイトを参考にしてください。
JenkinsにPythonのPATHを設定する
- サイドメニューの「Jenkinsの管理」を押します
- 「システムの設定」を押します
- 「グローバルプロパティ」のリストの「環境変数」を押します
- PCにインストールされているPythonのパスを設定します
mablのAPIキーを設定する
「mablの設定」で作成したAPI keyを利用します
- サイドメニューの「Jenkinsの管理」を押します
- 「Manage Credentials」を押します
- 「Stores scoped to Jenkins」のリストの「Domains」にある「(global)」を押します
- サイドメニューの「認証情報の追加」を押します
- 「種類」のプルダウンから「Seacret text」を選択し、以下の内容を入力します
(1) スコープ:グローバル
(2) Seacret:mablのAPI keyを入力
(3) ID:わかりやすいIDをつけておきます 例:mabl_API_key など
(4) 説明:使用目的がわかる説明を入れます - 「保存」を押します
連携手順⑤コードの実装
プロジェクトの構成
こちらがプロジェクトの構成です。上から順番に説明していきます。
Data/test_data.csv
連携手順③で作成したCSVファイルです。
Module/config.py
TestRailとGithubの接続に必要なトークンやログイン情報を記載します。
Jenkinsのジョブフォルダのパスはジョブ作成後に入力します。
# Githubの設定
token_github = "Githubのトークンを入れます"
base_url_github = "GithubのレポジトリのURLを入れます"
# TestRAilの設定
user_testrail = "TestRailのユーザーIDを入れます"
password_testrail = "TestRailのパスワードを入れます"
base_url_testrail = "TestRailのURLを入れます(index.php?の前の部分まで)"
# Jenkinsのジョブフォルダのパスの例
jenkins_folder = "C:\\Jenkinshome\\jobs\\mablTest_Run"
Module/github.py
GithubのAPIを利用するためのファイルです。
今回は以下の二つのAPIを使用します
- issueを作成するAPI
- 作成したissueのIDを取得するAPI
内容は前回の記事「TestRailと自動テストの連携#1 Selenium/Python編」とほぼ同じですが、issueの本文に失敗したmablのテスト結果URLを入れるようにしました。
import json
import requests
import Module.config as config
class GithubAPIClient:
def __init__(self):
self.GITHUB_TOKEN = config.token_github
self.base_url = config.base_url_github
def create_issue(self, title, body):
"""Githubにissueを作成する
"""
uri = f"/issues"
url = self.base_url + uri
headers = {}
headers['Authorization'] = 'Bearer ' + self.GITHUB_TOKEN
headers['Content-Type'] = 'application/json'
headers['Accept'] = 'application/vnd.github.v3+json'
data = {}
data["title"] = title
data["body"] = "こちらのリンクからテスト結果を確認してください。" + body
payload = bytes(json.dumps(data), 'utf-8')
response = requests.post(url, headers=headers, data=payload)
return response
def get_issues(self):
"""issueのデータを取得する。"
作ったすぐ後に取得するため、一番最初のnumberを取得するようになっています。
"""
uri = f"/issues"
url = self.base_url + uri
headers = {}
headers['Authorization'] = 'Bearer ' + self.GITHUB_TOKEN
# headers['Content-Type'] = 'application/json'
headers['Accept'] = 'application/vnd.github.v3+json'
response = requests.get(url, headers=headers)
return response.json()
class APIError(Exception):
pass
Module/testrail.py
TestRailのAPIを利用するためのファイルです。
前回の記事「TestRailと自動テストの連携#1 Selenium/Python編」と同じなので省略します。
main.py
mablのテスト結果をJenkinsのログから取得して、Githubに起票、TestRailにテスト結果の入力をします。
import csv
from Module.github import GithubAPIClient
from Module.testrail import APIClient
from Module.config import jenkins_folder
Github = GithubAPIClient()
TestRail = APIClient()
def load_csv():
"""csvファイルを読み込む。
"""
with open(r"Data\test_data.csv", encoding='utf-8') as test_data_file:
data = csv.DictReader(test_data_file)
read_data = [row for row in data]
return read_data
try:
# 次回のビルドナンバーをジョブフォルダ内の「nextBuildNumber」ファイルから取得する。
nextbuild_num = open(jenkins_folder + "\\nextBuildNumber", 'r')
# 今回のビルドナンバーはマイナス1
build_num = int(nextbuild_num.read()) - 1
nextbuild_num.close()
except:
# 初回は「nextBuildNumber」ファイルがないので 1
build_num = 1
# テスト結果のログが格納されているJenkinsのフォルダを指定
job_folder = jenkins_folder + "\\builds\\"
build_folder = job_folder + str(build_num)
# ログファイルを読み込む
log = open(build_folder + "\\log", 'r')
log_text = log.read()
# 全てのテスト結果が載っている一番最後の"Running mabl test(s) status update:"の位置を探す
start_point = log_text.rfind("Running mabl test(s) status update:")
# テスト終了時に出力される"The final plan states in mabl:"の位置を探す
end_point = log_text.find("The final plan states in mabl:")
# 必要な部分だけにする
slice_area = slice(start_point, end_point)
log_text = log_text[slice_area]
# 一行ずつリストにしておく
log_list = log_text.split("\n")
# 結果を入れる辞書を用意する
test_order = 1
test_data = {}
# Jenkinsのコンソールログから、テスト結果に必要な情報を取得する
for l in log_list:
# "Test ["の有無でテスト結果のテキストか判断する
start_point = l.find("Test [")
end_point = l.find("]")
if start_point < 0:
pass # findの結果が0未満の場合はテスト結果のテキストではない。処理しない。
else:
# 1. テスト名の抽出
# "Test [" から次の "]"までを切り取る処理
slice_area = slice(start_point + 6, end_point)
test_name = l[slice_area]
# 2. テスト結果の抽出
# Test [{テスト名}] is [" から次の "]"までを切り取る処理
start_point = l.find("] is [")
end_point = l.find("]", start_point + 1)
slice_area = slice(start_point + 6, end_point)
test_result = l[slice_area]
# Failed の時にだけ記載される"] as ["があるかを確認
start_point = l.find("] at [")
end_point = l.find("]", start_point + 1)
if start_point < 0:
test_data[test_order] = {"name": test_name,
"result": test_result, "link": ""}
test_order = test_order + 1
pass # 0未満の場合はFailedではないので処理しない
else:
# 3. faildのテスト結果のリンクを取得
# "] at ["から次の "]" までを切り取る処理
slice_area = slice(start_point + 6, end_point)
test_link = l[slice_area]
test_data[test_order] = {"name": test_name, "result": test_result, "link": test_link}
test_order = test_order + 1
# Githubに失敗したテストを起票
i = 1
while i < test_order:
if test_data[i]["result"] == "failed":
Github.create_issue("テスト失敗報告 : " + test_data[i]["name"], test_data[i]["link"])
# issue番号を取得してtest_dataに入れる
issue_data = Github.get_issues()
test_data[i]["issueNum"] = issue_data[0]["number"]
i += 1
else:
i += 1
pass
# Jenkinsのログのテスト順は読み込まれた順になるため、毎回並び順が異なる。
# TestRailにインポートしたテスト項目書「test_data.csv」のテスト名と、test_dataのテスト名を照合し、
# TestIDをtest_dataに追加する。
# WARNING: テスト名は全てユニークである必要があります。
# WARNING: mablのテスト名と完全に一致している必要があります。一文字でも違うとこれ以降の処理が失敗します。
t = load_csv()
i = 1
for csv_data in t:
y = csv_data["objectives"]
while i < test_order:
try: # すでにtestIDが入っているか確認。入っていたらtestID追加の処理はしない。
test_data[i]["testID"] == ".*"
except:
if test_data[i]["name"] == csv_data["objectives"]:
test_data[i]["testID"] = csv_data["testID"]
i = 1
break
else:
pass
i += 1
# TestRailに結果を入力する。
i = 1
while i < test_order:
if test_data[i]["result"] == "completed":
TestRail.post_test_result_Pass(test_data[i]["testID"])
i += 1
elif test_data[i]["result"] == "failed":
TestRail.post_test_result_Fail(test_data[i]["testID"],
"テストが失敗しました。欠陥のリンクを確認してください。",
str(test_data[i]["issueNum"]))
i += 1
elif test_data[i]["result"] == "skipped":
i += 1
pass
連携手順⑤Jenkinsのジョブを作成する
mablプラグインを利用し、指定したテストを実行する
- Jenkinsのサイドメニューから「新規ジョブ作成」を押します
- ジョブ名を入れます
- 「フリースタイル・プロジェクトのビルド」を選択し、「OK」を押します
- 「ビルド」にある「ビルド手順の追加」のプルダウンから「Run mabl tests」を選択し、以下の内容を入力します
(1) API Key Secret:前の手順で追加したmablのAPI Keyを選択します
(2) Application:テスト対象のアプリを選択します
(3) Environment:テスト対象の環境を選択します
テスト結果を入力するPythonファイルを実行する
1.「ビルド手順の追加」のプルダウンから「Windowsバッチコマンドの実行」を選択し、以下のコマンドを入力します
cd {サンプルプロジェクトのmain.pyがある場所}
python main.py
2.「保存」を押します
実行手順
上記の手順で作成したJenkinsのジョブを実行するだけです。
TestRailやGithubのページを更新すると、自動的に結果の入力やissueの作成がされていることを確認できます。
おわりに
「何だこのコードはっ!! よくもこんなコードをこの海〇〇山の前に出したなっ!!こんなコードで自動化連携ができるか、不愉快だっ!!」
となったそこのあなた。一緒に頑張って乗り越えましょう!