Модульное тестирование - зависимые тесты - PullRequest
3 голосов
/ 01 декабря 2011

Я создаю список модульных тестов, которые зависят друг от друга.Например, мой первый тест создает запись в базе данных и проверяет, что возвращаемое значение больше 0.

Второй тест затем проверяет данные записи, созданной в первом тесте.Однако для этого требуется идентификатор записи, созданной в первом тесте.

Первоначально я вызвал второй тест из первого теста, чтобы я мог передать идентификатор в качестве параметра, который работал нормально, за исключением того, что это означало, чтопо сути, был только один тест.

Я создал упорядоченный список с идентификатором, объявленным вне области, но после первого модульного теста это значение возвращается к 0, поэтому, очевидно, второй модульный тест не пройден.

Есть ли способ создать тесты, чтобы они разделяли значение, полученное в первом тесте?

Код ниже:

[TestMethod]
public void TestNewLandlord_InsertIntoImportFiles_ReturnFileID()
{
    try
    {
        DataSet ds = EngineBllUtility.InsertIntoImportFiles(connString, @"C:\Documents and Settings\dTrunley\My Documents", "HFISNewLandlordTest.csv",
        "TestNewLandlord()", WindowsIdentity.GetCurrent().Name, "HFIS Landlords", "NA", 30247531, false);

        importFileId = long.Parse(ds.Tables[0].Rows[0]["ImportFileID"].ToString());
        Assert.IsTrue(importFileId > 0);
    }
    catch (Exception ex)
    {
        Assert.Fail(ex.Message);
    }
}

[TestMethod]
public void TestNewLandlord_InsertIntoImportFiles_CorrectData()
{
    try
    {
        using (SqlConnection connectionString = new SqlConnection(connString))
        {
            using (SqlCommand sqlCommand = new SqlCommand(
                String.Format("SELECT * FROM [mydeposits].[import].[ImportFiles] WHERE [ImportFileID] = {0}", importFileId), connectionString))
            {
                connectionString.Open();
                using (SqlDataReader dr = sqlCommand.ExecuteReader())
                {
                    if (dr.HasRows)
                    {
                        bool correctData = true;
                        dr.Read();
                        if (!dr["ImportFileStatusID"].ToString().Equals("1"))
                            correctData = false;
                        if (!dr["HeadOfficeMemberID"].ToString().Equals("247531"))
                            correctData = false;
                        Assert.IsTrue(correctData);
                        TestCleanup();
                    }
                    else
                        throw new Exception("Import does not exist in database");
                }
            }
        }
    }
    catch (Exception ex)
    {
        Assert.Fail(ex.Message);
        TestCleanup();
    }
}

Ответы [ 2 ]

6 голосов
/ 01 декабря 2011

Я создаю список модульных тестов, которые зависят друг от друга.Например, мой первый тест создает запись в базе данных и проверяет, что возвращаемое значение больше 0.

На мой взгляд, такой подход неверен.Вы можете создать злой код, который вас укусит.Такой код:

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

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

Еще одним преимуществом является то, что вы можете запускать тесты параллельно.Для больших систем важно, чтобы цикл непрерывной интеграции (и развертывания) был быстрым.Выполняя параллельные тесты, вы можете значительно ускорить цикл выпуска.

Предлагаемое решение

Возможно, вы пытаетесь выполнить интеграционные тесты.Один из способов написать их - создать отдельный проект для таких тестов.Каждый тест по-прежнему будет независимым друг от друга, но, вероятно, для каждого теста потребуются некоторые значения SetUp и TearDown в терминах теста NUnit.Таким образом, SetUp подготовит все необходимое для прохождения интеграционных тестов, а TearDown выполнит очистку после каждого теста.

3 голосов
/ 01 декабря 2011

Это очень непослушно, однако вы можете отменить комментарий (если он создан мастером тестирования или добавить)

//You can use the following additional attributes as you write your tests:

//Use ClassInitialize to run code before running the first test in the class
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
}

//Use ClassCleanup to run code after all tests in a class have run
[ClassCleanup()]
public static void MyClassCleanup()
{
}

//Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
}

//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
}

Ничем не отличается от макета некоторых распространенных тестовых данных, хотя и сомнительным.

...