Это будет открыто для многих дебатов, но непрерывная интеграция и TDD идут рука об руку. Вам нужно больше, чем просто "он компилируется?" уровень тестов для обеспечения надежности постоянно меняющегося кода.
Если вы соблюдаете высокую степень охвата тестирования, то любая функция, которую вы нажимаете, будет полностью протестирована в рамках сборки, прежде чем она будет принята. Это означает, что вы должны кодировать таким образом, чтобы вы могли быстро получить целые фрагменты функциональности, а затем наращивать их, а не наращивать. (вертикальная нарезка).
Что это значит с точки зрения кода?
Вам необходимо сильно полагаться на Принцип обращения зависимостей
Вместо этого:
public class PersonService
{
private SqlDataAccess DataAccess = new SqlDataAccess();
public void SavePerson(Person person)
{
DataAccess.SavePerson(person);
}
}
Вы должны сделать это:
public class PersonService
{
private IDataAccess DataAccess {get; set;}
public PersonService(IDataAccess dataAccess)
{
if(dataAccess == null)
throw new ArgumentNullException("dataAccess");
DataAccess = dataAccess;
}
public void SavePerson(Person person)
{
DataAccess.SavePerson(person);
}
}
Это простой пример, но он предлагает вам возможность принять решение, например, реализовать уровень доступа к данным в памяти, одновременно расширяя пользовательский интерфейс и основные функции. Тесты все еще могут быть написаны, потому что вы можете издеваться над сервисом, и вы можете продвигать функциональность быстрее, так как не каждая часть должна быть на 100%. Когда требования начинают укрепляться, вы можете принять более обоснованное решение о доступе к данным и просто заменить временный компонент более постоянным, не беспокоясь о нарушении существующего кода.
И, конечно, у вас будет автоматические интеграционные тесты, запущенные, чтобы гарантировать, что вы не нарушите остальную часть своей базы кода;)