Дублируйте поведение теста, управляемого данными

Прямо сейчас, если у вас есть тест, который выглядит так:

[TestMethod]
[DeploymentItem("DataSource.csv")]
[DataSource(
    Microsoft.VisualStudio.TestTools.DataSource.CSV, 
    "DataSource.csv", 
    "DataSource#csv", 
    DataAccessMethod.Sequential)]
public void TestSomething()
{
    string data = TestContext.DataRow["ColumnHeader"].ToString();
    /* 
    do something with the data
    */
}

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

Что я хотел бы сделать, так это дублировать такое поведение в коде, сохраняя при этом источник данных. Например: предположим, что я хочу запустить этот тест для нескольких развернутых версий веб-службы (это функциональный тест, поэтому ничего не имитируется, т. е. это вполне может быть тест codedui для веб-сайта, развернутого на нескольких хосты).

[TestMethod]
[DeploymentItem("DataSource.csv")]
[DataSource(
    Microsoft.VisualStudio.TestTools.DataSource.CSV, 
    "DataSource.csv", 
    "DataSource#csv", 
    DataAccessMethod.Sequential)]
public void TestSomething()
{
    var svc = helper.GetService(/* external file - NOT a datasource */);
    string data = TestContext.DataRow["ColumnHeader"].ToString();
    /* 
    do something with the data
    */
}

Теперь, если у меня есть 2 местоположения развертывания, указанные во внешнем файле, и 2 значения в источнике данных для метода тестирования, я должен получить 4 теста.

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

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

Может ли кто-нибудь указать мне некоторую информацию, которая может помочь мне решить эту мою проблему?


person Steven Evers    schedule 04.08.2011    source источник


Ответы (1)


ОБНОВЛЕНИЕ! Это работает для Visual Studio 2010, но не работает в 2012 и 2013.

У меня была аналогичная проблема, когда у меня была куча файлов, которые я хотел использовать в качестве тестовых данных в тесте, управляемом данными. Я решил это, сгенерировав CSV-файл перед выполнением теста, управляемого данными. Генерация происходит в статическом методе, украшенном атрибутом ClassInitialize.

Я думаю, вы могли бы сделать что-то подобное и объединить свой текущий источник данных с вашим «внешним файлом» и вывести новый источник данных CSV, который использует ваш тест, основанный на данных.

public TestContext TestContext { get; set; }
const string NameColumn = "NAME";
const string BaseResourceName = "MyAssembly.UnitTests.Regression.Source";

[ClassInitialize()]
public static void Initialize(TestContext context)
{
    var path = Path.Combine(context.TestDeploymentDir, "TestCases.csv");
    using (var writer = new StreamWriter(path, false))
    {
        // Write column headers
        writer.WriteLine(NameColumn);

        string[] resourceNames = typeof(RegressionTests).Assembly.GetManifestResourceNames();
        foreach (string resourceName in resourceNames)
        {
            if (resourceName.StartsWith(BaseResourceName))
            {
                writer.WriteLine(resourceName);
            }
        }
    }
}

[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\TestCases.csv", "TestCases#csv", DataAccessMethod.Random)]
public void RegressionTest()
{
    var resourceName = TestContext.DataRow[NameColumn].ToString();
    // Get testdata from resource and perform test.
}
person Magnus Lindhe    schedule 09.11.2011
comment
Я думал об этом. Это не идеально, но я думаю, что это настолько близко, насколько я собираюсь получить. Я отмечу это как ответ. Спасибо Магнус. - person Steven Evers; 09.11.2011
comment
Для тех, кто нашел это, я не мог заставить это работать, по крайней мере, на VS2013. Кажется, что файлы csv должны существовать по целевому пути до начала любого выполнения, и они считываются до запуска метода ClassInitialize, поэтому динамическая генерация ничего не делает... - person kkara; 30.12.2013
comment
@kkara Подтверждено, у меня была точно такая же проблема. - person Alex Marshall; 20.09.2015
comment
Это не работает и для 2015 года. Я пробовал и с [ClassInitialize], и с [AssemblyInitialize]. - person Paul Nelson Baker; 11.07.2016