Самый простой способ вкотиться в автоматическое тестирование - REST API часть 2

29.06.2020 04:18

Оглавление

  1. Подготовка
  2. Пишем автотесты <-- вы здесь
  3. Дополнение (в процессе)

Сейчас мы уже знаем, что такое инструменты разработчика в браузере, умеем отправлять curl запросы из терминала, и умеем пользоваться автоматической документацией.

Теперь преступаем к автотестам.

Что такое автотест REST API ? Это всего лишь отправка запроса на сервер и проверка корректности ответа. Наример, отправим запрос к главной странице этого сайта:

curl https://allwebstuff.info/ -v

Возвращает ответ:

Код ответа "< HTTP/1.1 200 OK" - успешно, запрос вернул какие-то не нулевые данные, значит тест пройден успешно.

Теперь нужно сделать то же самое из nodejs. Инициируем npm, на все вопрсы просто отвечаем yes:

npm init

Затем ставим пару необходимых пакетов:

npm i axios mocha sync-request @hapi/joi

Открываем package.json, в нём нужно подправить строчку с тестами, должно быть вот так:

{
  "name": "autotesting",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@hapi/joi": "^17.1.1",
    "axios": "^0.19.2",
    "mocha": "^8.0.1",
    "sync-request": "^6.1.0"
  }
}

И вот теперь пишим первый тест, создаём папку test, и в ней файл simple_test.js

//simple_test.js
const axios = require('axios');

describe('My first test pack', function(){
  it('My first test case', async function() {
    await axios('https://allwebstuff.info/');
  });
}); 

Запускаем тест:

Поздравляю, мы написали первый автотест, он точно так же отправляет запрос на https://allwebstuff.info/ и проверяет ответил ли сервер без ошибок. Это называется позитивный тест, так как мы ожидаем позитивный ответ.

Теперь добавим негативный тест, нужно послать запрос на несуществующую страницу, сервер ответит ошибкой, ошибку нужно поймать и обработать:

const axios = require('axios');

describe('My first test pack', function(){
  
  it('My first positive test case', async function() {
    await axios('https://allwebstuff.info/');
  });
  
  it('My first negative test case', async function() {
    try {
      await axios('https://allwebstuff.info/404');
    } catch {
      // Ниделаем ничего, так как ответ с ошибкой мы и ожидаем
      return;
    }
    // А вот, если ошибки не было, то это непорядок, нужно выбросить ошибку, чтобы тест упал
    throw new Error('Test not passed');
  });
  
}); 

Проверяем:

Приступаем к REST API

Так как на нашем сервере запросы закрыты авторизацией, перед всеми тестами, нужно авторизоваться, сделать это нужно синхронным запросом, чтобы он гарантированно выполнился до всего остального:

// rest_1.js
const axios = require('axios');
const request = require('sync-request');

let authResponse = request('POST', 'http://0.0.0.0:3030/api/auth', {
  json: {
    password: '12345',
    email: 'pupkin@gmail.com'
  },
});

let authToken = JSON.parse(authResponse.getBody('utf8')).data[ 0 ];

describe( 'Auth test pack', function() {
  
  it('get: /api/auth', async function() {
    
    let options = {
      url: 'http://0.0.0.0:3030/api/auth',
      method: 'GET',
      headers: {
        authorization: `Bearer ${authToken.token}`
      }
    }
    
    let result = await axios(options);
    
    console.log('** result', result.data);
    
  })
  
});

Но проверить код ответа мало, нужно ещё проверить, что за данные вернул сервер. Для этого нужно описать схемы данных:


const axios = require('axios');
const Joi = require('@hapi/joi');
const request = require('sync-request');

let authResponse = request('POST', 'http://0.0.0.0:3030/api/auth', {
  json: {
    password: '12345',
    email: 'pupkin@gmail.com'
  },
});

let authToken = JSON.parse(authResponse.getBody('utf8')).data[ 0 ];

let authResponce = Joi.object({
  data: Joi.array().items(Joi.object({
    id: Joi.number().integer().min(1),
    token: Joi.string(),
    user_id: Joi.number().integer().min(1),
    expiresAt: Joi.date(),
    createdAt: Joi.date(),
    updatedAt: Joi.date(),
    user: Joi.object({
      id: Joi.number().integer().min(1),
      name: Joi.string(),
      email: Joi.string(),
      role: Joi.number().integer().min(0),
      status: Joi.number().integer().min(0),
      createdAt: Joi.date(),
      updatedAt: Joi.date(),
    })
  })),
  meta: Joi.object({
    total: Joi.number().integer().min(0),
    count: Joi.number().integer().min(0),
    offset: Joi.number().integer().min(0),
    error: null
  })
});

let messagesResponce = Joi.object({
  data: Joi.array().items(Joi.object({
    id: Joi.number().integer().min(1).required(),
    recipient_id: Joi.number().integer().min(1).required(),
    message: Joi.string().required(),
    status: Joi.number().integer().min(0),
    viewDate: Joi.date().allow(null),
    sender_id: Joi.number().integer().min(1).required(),
    createdAt: Joi.date().required(),
    updatedAt: Joi.date().required(),
  })).required(),
  meta: Joi.object({
    total: Joi.number().integer().min(0).required(),
    count: Joi.number().integer().min(0).required(),
    offset: Joi.number().integer().min(0).required(),
    error: null
  }).required()
});


let testScheme = Joi.object();

describe( 'Test pack with responce scheme', function() {
  
  it('get: /api/auth', async function() {
    let options = {
      url: 'http://0.0.0.0:3030/api/auth',
      method: 'GET',
      headers: {
        authorization: `Bearer ${authToken.token}`
      }
    }
    
    let result = await axios(options);    
    Joi.assert(result.data, authResponce);
  });
  
  it('post: /api/messages', async function() {
    let options = {
      url: 'http://0.0.0.0:3030/api/messages',
      method: 'post',
      headers: {
        authorization: `Bearer ${authToken.token}`
      },
      data: {
        recipient_id: 1,
        message: 'Test message'
      }
    };
    let result = await axios(options);
    Joi.assert(result.data, messagesResponce);
  });

  it('get: /api/messages', async function() {
    let options = {
      url: 'http://0.0.0.0:3030/api/messages',
      method: 'get',
      headers: {
        authorization: `Bearer ${authToken.token}`
      }
    };
    let result = await axios(options);
    Joi.assert(result.data, messagesResponce);
  });
  
});

authResponce и messagesResponce и есть схемы ответа сервера, в случае, если сервер пришлёт данные не совподяющие с этими схемами, тест упадёт:

И вся работа по написанию REST автотестов будет заключаться в содании таких схем, и посылании однотипных запросов.

Просто берёте шаблоны из этой статьи, делаеете ctrl+c/ctrl+v немного их подпровляете, и готово.

vk f tw in

vk f tw in

ASUS ROG Zephyrus G15 GA502IU, почему я его вернул в магазин

Успел его поюзать всего пару дней, и тут же вернул. Из-за противного писка в левом вентиляторе. Не монотонного шума, как на правом вентиляторе, а именно писка, из-за вибрации.


(0) Комментариев