Automated test management with Telegram

As a QA engineer, I developed a self-test system. Faced a number of problems:





Therefore, I decided to create a small prototype of the bot to run automated tests, which would cover most of the problems described above.



Description of the idea:



The user sends the necessary commands to the chat, launches the build in the CI system, according to the specified rules in the config. CI runs autotests with pytest marks. After the run, the script inside the test repository receives information about the build state, collects logs and sends it back to the user in telegram chat.



Instruments:



Instruments
  • Programming Language - Python
  • Test Framework - Pytest
  • HTTP client - Requests
  • DataBase - SQLite3
  • ORM - Peewee
  • CI system - Travis CI






Content



  1. Training
  2. Bot Registration
  3. Preparing a test repository
  4. Tests and Logging
  5. Report generation
  6. Configure Travis CI
  7. Bot setup
  8. The principles of the bot
  9. Deployment on Heroku




Bot Registration



First of all, we need to register the telegram of the bot and get its unique id, which is a token. To do this, write the message / start to the @BotFather bot.

Our main team is / newbot, by entering which we will be asked to come up with the name of the bot.

But there is one rule - the name must end in bot. BotFather accepts the bot name and returns your token. Activate the bot by starting chatting. Next, you need to send a request to the API on the getUpdates method.



https://api.telegram.org/bot{_}/getUpdates
      
      





Remember the received hat_id.





Preparing a test repository



Next, you need to organize a repository with tests, or use a pre- prepared article.





Tests and Logging



Create test functions and mark them with the pytest mark - full, smoke and bird.



It is important to add logging to our tests by creating the pytest.ini file and adding the calls to the info method from the logging library in the test functions.

The pytest.ini file contains templates for live logs and a log file.



Test example
 import pytest import requests import logging @pytest.mark.full @pytest.mark.smoke def test_cat_facts(): query = {"animal_type": "cat", "amount": "2"} response = requests.get("https://cat-fact.herokuapp.com/facts/random", params=query) logging.info(f"Request url: {response.request.url}, body: {response.request.body}") logging.info(f"Request status: {response.status_code}, body: {response.text}") assert response.status_code == 200 @pytest.mark.full @pytest.mark.smoke def test_dog_facts(): query = {"animal_type": "dog", "amount": "2"} response = requests.get("https://cat-fact.herokuapp.com/facts/random", params=query) logging.info(f"Request url: {response.request.url}, body: {response.request.body}") logging.info(f"Request status: {response.status_code}, body: {response.text}") assert response.status_code == 200 @pytest.mark.full def test_horse_facts(): query = {"animal_type": "horse", "amount": "2"} response = requests.get("https://cat-fact.herokuapp.com/facts/random", params=query) logging.info(f"Request url: {response.request.url}, body: {response.request.body}") logging.info(f"Request status: {response.status_code}, body: {response.text}") assert response.status_code == 200 @pytest.mark.bird def test_bird_facts(): query = {"animal_type": "bird", "amount": "2"} response = requests.get("https://cat-fact.herokuapp.com/facts/random", params=query) logging.info(f"Request url: {response.request.url}, body: {response.request.body}") logging.info(f"Request status: {response.status_code}, body: {response.text}") assert response.status_code == 200
      
      









pytest.ini
 [pytest] markers = smoke: for smoking testing full: for regression testing bird: facts only bird log_cli = 1 log_cli_level=INFO log_cli_format = %(asctime)s [%(levelname)8s] %(message)s log_cli_date_format='%Y-%m-%d %H:%M:%S' log_file = test_log.log log_file_level=INFO log_file_format= %(asctime)s [%(levelname)8s] %(message)s log_file_date_format='%Y-%m-%d %H:%M:%S'
      
      











Report generation



We create a script that, after completion of the assembly, collects information from the CI system and send them to telegram chat, together with the logs.

Inside the script, you need to replace the TELEGRAM_BOT and CHAT_ID values ​​with the ones you received earlier.



Script code
 import requests import os TRAVIS_TEST_RESULT = os.environ.get("TRAVIS_TEST_RESULT") TRAVIS_REPO_SLUG = os.environ.get("TRAVIS_REPO_SLUG") TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH") TRAVIS_JOB_WEB_URL = os.environ.get("TRAVIS_JOB_WEB_URL") TRAVIS_COMMIT_MESSAGE = os.environ.get("TRAVIS_COMMIT_MESSAGE") TELEGRAM_TOKEN = "808619876:GHrtj9zs-KvKhhtWyu1YoxjtIikUYMGVjD8g" CHAT_ID = "272560060" if TRAVIS_TEST_RESULT != 0: build_status = "" else: build_status = "" TEXT = f" : {build_status} \n : {TRAVIS_REPO_SLUG} \n : {TRAVIS_BRANCH} \n Commit : {TRAVIS_COMMIT_MESSAGE} \n -: {TRAVIS_JOB_WEB_URL}" def send_message(): URL = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage" body = {'chat_id': CHAT_ID, 'text': TEXT} response = requests.post(url=URL, json=body) return response def send_file(): URL = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendDocument" body = {'chat_id': CHAT_ID} file = {"document": open("test_log.log")} response = requests.post(url=URL, data=body, files=file) return response send_message() send_file()
      
      







The script uses system variables and receives values ​​from Travis CI.



If the value of TRAVIS_TEST_RESULT is not equal to zero - the value is set to “Successfully”, the send_message function is first executed, which sends assembly information to the chat (repository name, selected branch, name of the commit used, link to the web log), then the send_file function that sends log file.



In the test repository, add the configuration file - travis.yml. Inside we describe the pipeline through which the assembly will work.



travis.yml
 language: python python: - "3.7" install: - pip install -r requirements.txt script: pytest -m smoke after_script: - python tg_command.py
      
      







Next, we need to deploy the repository on GitHub to add it to Travis CI.





TRAVIS_CI setting



We go to the site .

Log in using your GitHub account. Switch to the Dashboard tab. Having previously opened DevTools (Network), in the Repositories sub-tab on the site opposite the test repository, move the slider - activate its assembly. In the Network tab (DevTools), an active request comes in, in the preview of which there is information about the id of the repository, the number must be remembered (copy / write). Switching to the site in the Setting tab. We copy or remember the token - we need it.





Bot setup



In this article, we will not dwell on the analysis of the code, you can see it in the repository . Now it’s important for us to understand the basics of the topic, so let's move on to setting up our bot:



Inside the repository are the files:



  1. main.py - bot script;
  2. models.py - file with models for ORM;
  3. conf.ini - file with configuration variables;
  4. runtime.txt - fixed Python version value for Travis CI;
  5. procfile - setting for gunicorn;
  6. wsgi.py - application launch file with gunicorn.


To make your bot work, you need to replace the data in conf.ini, namely:





Conf.ini example
 [travis] travis_token = token HkjhkjgGKJhjgFGfdgd travis_base_url = https://api.travis-ci.org travis_repository_id = 10898384 [telegram] telegram_chat_id = 24234234 telegram_bot_url = https://api.telegram.org/bot87543366:AAHtj9zs-Kv4zGWyu1eTXegikUYMGVjD8g/
      
      









The principles of the bot



It is important that each request must give a response status of 200. Otherwise, the telegram begins to send requests cyclically until it receives a valid response.



The bot has a set of commands:



The delimiter can be any special characters except the underscore.





How does the bot work?



1. The user adds a set of tests (add_m):

The command splits the user data into 2 parts - the description and name of the branch in git. The name is written in the mark_name column inside the database, and the description in the mark_description column.



2. The user adds branches (add_b):

The command splits the user data into 2 parts - the description and name of the branch in git. The name is written in the branch_name column inside the database, and the description in the branch_description column.



3. The user selects the default branch (select):

The user receives buttons in the chat, formed according to the data from the tables branch_description and branch_name. The user selects a button with the desired branch. It is written to the favorite_branch table.



4. The user starts the build initialization (run):

The user receives buttons in the chat, formed according to the data from the tables

mark_description and mark_name. The user selects a button with a kit to run autotests.



Based on the data selected by the user, the bot generates a request in the trigger method in the TravisCI class and sends it to Travis for execution. Inside the Travis system, the trigger a build option is activated. This option overrides the travis.yml file, changing the script section to user-selected data.





Deployment on HEROKU



For the bot to work, it must be deployed to the hosting. I recommend using Heroku, because this platform has a free tariff, which provides the necessary power for the bot to work.



How to deploy a bot?



In order not to describe the whole process, I will leave a link to the official documentation for the start:



If you want to work with Heroku through the GUI, fill in the code on Github. You need to register through the Heroku web interface. After registration, click New -> Create new app -> Enter the name of the app and select a region. Go to the Deploy tab and choose the integration with Github in the Deployment method.



Before us appears a block for searching the repository. Enter the name of the repository and click the Search button. In the search results, opposite the repository name, click the Connect button. In the Manual deploy block, select the branch and click “Deploy”.



Last moment - you need to activate webhooks using a GET request:

 https://api.telegram.org/bot{id_}/setWebhook?url=https://{_}.herokuapp.com/bot
      
      







The bot can be used. We check that everything worked out for us:



image







All Articles