Написание тестов интеграции программного обеспечения часто может быть более сложной задачей, чем код, который они должны тестировать. Целью написания этих тестов является проверка того, что компоненты или приложения работают вместе, как ожидается, для соответствия определенным пользовательским сценариям.

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

const expect = require('chai').expect;
describe('Part 1 of Application A', () => {
  let result;
it('should perform task A of process X', () => {
    result = performTaskA();
    expect(result).to.equal('OK');
  });
it('should perform task B of process X', () => {
    result = performTaskB(result);
    expect(result).to.equal('OK');
  });
});

В приведенном выше гипотетическом примере выполнение PerformTaskB зависит от результата, полученного от PerformTaskA. Хотя это гипотетически, многие реальные сценарии следуют этому шаблону, когда необходимы данные из предыдущего теста для успешного запуска последующего теста.

Проблема с этим, конечно, в том, что тесты зависят друг от друга. Если первый тест в нашем гипотетическом сценарии не пройден, то и второй тоже.

Чтобы избежать этой проблемы, нам нужно убедиться, что тесты независимы, генерируя необходимые им данные вне других тестов.

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

const expect = require('chai').expect;
describe('Part 1 of Application A', () => {
  describe('Task A' () => {
    it('should perform task A of process X', () => {
      expect(performTaskA()).to.equal('OK');
    });
  });
describe('Task B' () => {
    let data;
before('Create needed data', () => {
      data = performTaskA();
    });
it('should perform task B of process X', () => {
      expect(performTaskB(data)).to.equal('OK');
    });
  });
});

В этой альтернативной реализации мы разделили тесты на корзины задачи A и задачи B и добавили шаг before для создания необходимых данных в задаче B.

В целом, делая интеграционные тесты независимыми, вы избавляетесь от необходимости определять, что не удалось, когда один тест приводит к провалу всех. Важно убедиться, что не только генерируются необходимые данные, но и что состояния и конфигурации системы также правильно настроены самим набором тестов.

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

Автор Карлос Раймер. Первоначально опубликовано здесь.