XUnit выводит больше информации, когда тест не пройден - PullRequest
1 голос
/ 08 апреля 2019

Кто-нибудь знает, как добавить дополнительную информацию в вывод, если тест XUnit не пройден? Я думаю, это было бы полезно иметь. Например, я обрабатываю тестовые файлы, я хотел бы увидеть, какой из них не удалось.

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

1 Ответ

0 голосов
/ 11 мая 2019

Если у вас есть xUnit, записывает результаты в файлы xml, например, говоря xUnit в командной строке, чтобы записать файл результатов XML, вы можете постобработать результаты из файлов XML, чтобы получить более подробную информацию о сбоях, с небольшим количеством кода C # (или вставьте ваш любимый язык вместо C #, например, Python, Java и т. д.

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

Вот пример кода для этого в C #. Ограничением этого кода является то, что он ожидает только одну сборку в узле «сборки» в XML.

public void ReadResultsXmlFile(string testResultsXmlFile)
{
    using (MyXmlTextReader = new XmlTextReader(testResultsXmlFile))
    {
        testResultXmlDocument = new XmlDocument();
        testResultXmlDocument.Load(MyXmlTextReader); // suppose that myXmlString contains "<Names>...</Names>"
        XmlNode xnAssembliesHeader = testResultXmlDocument.SelectSingleNode("/assemblies");
        TestRunDateTime = xnAssembliesHeader.Attributes.GetNamedItem("timestamp").Value;
        XmlNodeList xnAssemblyList = testResultXmlDocument.SelectNodes("/assemblies/assembly");
        foreach (XmlNode assembly in xnAssemblyList)
        {
            XmlNodeList xnTestList = testResultXmlDocument.SelectNodes(
                "/assemblies/assembly/collection/test");
            foreach (XmlNode test in xnTestList)
            {
                TestName = test.Attributes.GetNamedItem("name").Value;
                TestDuration = test.Attributes.GetNamedItem("time").Value;
                PassOrFail = test.Attributes.GetNamedItem("result").Value;
                // Failed test, get the failure information
                if (!(PassOrFail == "Pass"))
                {
                    Passed = false;
                    XmlNode failureData = test.SelectSingleNode("failure");
                    FailureText = failureData.InnerText;
                    StackTrace = failureData.SelectSingleNode("stack-trace").InnerText;
                    FailureMessage = failureData.SelectSingleNode("message").InnerText;
                    Console.WriteLine("Test: {0} Result: {1}  Error: {2}  StackTrace: {3}", TestName, PassOrFail, FailureMessage, FailureStackTrace);
                }
                else
                {
                    Passed = true;
                }
                Console.WriteLine("Test: {0} Result: {1}  Elapsed: {2}", TestName, PassOrFail, TestDuration);
            }
        }
    }
}

Потребуются приблизительно такие объявления, например, как часть того же класса:

public class MyTestAssembly
{
    public string TestName { get; set; }
    public string PassOrFail { get; set; }
    public bool Passed { get; set; }
    public string TestOutcome { get; set; }
    public string AlertLevel { get; set; }  // None, Warning, Alert
    public string AssemblyName { get; set; }
    public string AssemblyPath { get; set; }
    public string TestRunDateTime { get; set; }
    public TimeSpan testDuration;
    public string TestDuration { get; set; }
    public DateTime TestStartTime { get; set; }
    public DateTime TestStopTime { get; set; }
    public string TestResultsXmlFile { get; set; }
    public string FailureMessage { get; set; }
    public string StackTrace { get; set; }
    public string FailureStackTrace { get; set; }
    //todo: Report an error if more than one assembly exists under assemblies node
    public XmlDocument testResultXmlDocument;
    public string FailureText { get; set; }
    private XmlNodeList MyListOfTestAssembliesInResultsFile { get; set; }
    private XmlTextReader MyXmlTextReader;
    public double TestDurationSeconds;
    // And more stuff... this is only a partial example, extracted from working code.
}

Файлы результатов XUnit, с которыми я работаю, взяты из xUnit 2.4.x, .NET Framework и выглядят так:

<?xml version="1.0" encoding="utf-8"?>
<assemblies timestamp="05/06/2019 19:06:38">
  <assembly name="C:\Program Files (x86)\RunXUnitTests\TestAssemblies\HRCafeORT.DLL" environment="64-bit .NET 4.0.30319.42000 [collection-per-class, parallel (4 threads)]" test-framework="xUnit.net 2.4.1.0" run-date="2019-05-06" run-time="19:06:30" config-file="C:\Program Files (x86)\RunXUnitTests\TestAssemblies\xunit.console.exe.Config" total="1" passed="0" failed="1" skipped="0" time="7.376" errors="0">
    <errors />
    <collection total="1" passed="0" failed="1" skipped="0" name="Test collection for HRCafeORT.HRCafeWebsiteORTFeature" time="6.814">
      <test name="Ensure Intranet Application HR Cafe is available and working properly." type="HRCafeORT.HRCafeWebsiteORTFeature" method="EnsureIntranetApplicationHRCafeIsAvailableAndWorkingProperly_" time="6.8143311" result="Fail">
        <traits>
          <trait name="FeatureTitle" value="HR Cafe Website ORT" />
          <trait name="Description" value="Ensure Intranet Application HR Cafe is available and working properly." />
          <trait name="Category" value="HRCafe" />
          <trait name="Category" value="IE" />
        </traits>
        <failure exception-type="OpenQA.Selenium.ElementNotInteractableException">
          <message><![CDATA[OpenQA.Selenium.ElementNotInteractableException : Element cannot be interacted with via the keyboard because it is not focusable]]></message>
          <stack-trace><![CDATA[   at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
   at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Remote.RemoteWebElement.Execute(String commandToExecute, Dictionary`2 parameters)
   at HRCafeORT.HRCafeWebsiteORTSteps.GivenIHaveSelectedTheLeaveSelection() in C:\AppTest\ORT\HRCafeORT\HRCafeWebsiteORTSteps.cs:line 49
   at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance)
   at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
   at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
   at HRCafeORT.HRCafeWebsiteORTFeature.ScenarioCleanup()
   at HRCafeORT.HRCafeWebsiteORTFeature.EnsureIntranetApplicationHRCafeIsAvailableAndWorkingProperly_() in C:\AppTest\ORT\HRCafeORT\HRCafe.feature:line 14]]></stack-trace>
        </failure>
      </test>
    </collection>
  </assembly>
</assemblies>

Типичная командная строка xUnitConsole для консоли запуска теста будет выглядеть ниже. -Xml, за которым следует имя выходного файла, указывает файл результатов XML, который будет создан во время выполнения.

"C:\RunXUnitTests\TestAssemblies\xunit.console.exe" "C:\RunXUnitTests\TestAssemblies\HRCafeORT.DLL"  -xml "C:\Users\Public\Documents\TestResults\HRCafeORT.xml"
...