Как получить имя метода единичного теста во время выполнения внутри модульного теста?

17

Как получить имя тестового модуля из теста внутри устройства?

У меня есть метод ниже в классе BaseTestFixture:

public string GetCallerMethodName()
{
    var stackTrace = new StackTrace();
    StackFrame stackFrame = stackTrace.GetFrame(1);
    MethodBase methodBase = stackFrame.GetMethod();
    return methodBase.Name;
}

Класс My Test Fixture наследуется от базового:

[TestFixture]
public class WhenRegisteringUser : BaseTestFixture
{
}

, и у меня есть следующий системный тест:

[Test]
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully_WithValidUsersAndSites()
{
    string testMethodName = this.GetCallerMethodName();
    //
}

Когда я запускаю это из Visual Studio, он возвращает имя моего метода тестирования, как ожидалось.

Когда это выполняется TeamCity, вместо этого возвращается _InvokeMethodFast() , который, похоже, является методом, который TeamCity генерирует во время выполнения для собственного использования.

Итак, как я могу получить имя метода тестирования во время выполнения?

    
задан The Light 12.03.2012 в 12:55
источник
  • Скомпилировано ли оно в режиме выпуска даже при запуске из VS? –  Adriano Repetti 12.03.2012 в 12:57
  • Вы получаете информацию о сборке для каждого метода, вызванного в стеке? Возможно, вы могли бы подойти к стеку, ища тестовую сборку. –  George Duckett 12.03.2012 в 13:00
  • Элемент stacktrace поможет, чтобы узнать, указано ли имя фактического метода дальше в стеке вызовов. –  Joachim Isaksson 12.03.2012 в 13:01
  • У вас более 60 вопросов без принятия. Находите ли вы уважительно к людям, которые помогают вам? –  Rune FS 12.03.2012 в 13:07

5 ответов

17

Если вы используете NUnit 2.5.7 / 2.6 , вы можете использовать Класс TestContext :

[Test]
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully()
{
    string testMethodName = TestContext.CurrentContext.Test.Name;
}
    
ответ дан nemesv 12.03.2012 в 13:00
источник
  • Хорошая особенность :) –  The Light 12.03.2012 в 13:46
  • MSTest также предоставляет эту информацию в своем TestContext, а также –  bryanbcook 13.03.2012 в 06:39
  • Теперь он отлично работает с TeamCity, но когда я запускаю его локально из Visual Studio, он генерирует исключение, которое не инициализируется объектом. Итак, как заставить его работать в Visual Studio? –  The Light 15.03.2012 в 12:19
  • @William Wich test runner вы используете? –  nemesv 15.03.2012 в 12:50
11

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

[TestClass]
public class MyTestClass
{
    public TestContext TestContext { get; set; }

    [TestInitialize]
    public void setup()
    {
        logger.Info(" SETUP " + TestContext.TestName);
        // .... //
    }
}
    
ответ дан Candide Guevara Marino 24.11.2015 в 14:39
источник
7

Если вы не используете NUnit, вы можете перебирать стек и находить метод тестирования:

foreach(var stackFrame in stackTrace.GetFrames()) {
  MethodBase methodBase = stackFrame.GetMethod();
  Object[] attributes = methodBase.GetCustomAttributes(typeof(TestAttribute), false);
  if (attributes.Length >= 1) {
    return methodBase.Name;
  } 
}
return "Not called from a test method";
    
ответ дан Michael Lloyd Lee mlk 12.03.2012 в 13:20
источник
  • Знаете ли вы, что это работает только на MSTest? Или он будет работать как на NUnit, так и на MSTest? –  Yoiku 10.12.2015 в 17:02
  • Вам нужно будет изменить аннотацию как правильную аннотацию для тестовой среды. Однако, как указывает принятый ответ, NUnit имеет TestContext, который является лучшим решением. –  Michael Lloyd Lee mlk 15.12.2015 в 18:32
  • Спасибо за ответ, я спрашивал, потому что я пытаюсь построить FW, и я не хочу ограничивать себя NUnit или MSTest. Поэтому я думаю, что я сделаю это, чтобы зациклить стек снизу вверх, пока не найду метод, которым это пространство имен не является Microsoft или System. Я пробовал это, и получил хорошие результаты с MSTest и вызвал FW из командной строки (я получил основной метод). –  Yoiku 16.12.2015 в 19:59
  • обратите внимание, что в версиях Release это иногда не работает - метод проверки может быть встроен, и вы не сможете увидеть TestAttribute –  imaximchuk 05.10.2017 в 01:18
5

Спасибо, ребята; Я использовал комбинированный подход, поэтому теперь он работает во всех средах:

public string GetTestMethodName()
{
    try
    {
        // for when it runs via TeamCity
        return TestContext.CurrentContext.Test.Name;
    }
    catch
    {
        // for when it runs via Visual Studio locally
        var stackTrace = new StackTrace(); 
        foreach (var stackFrame in stackTrace.GetFrames())
        {
            MethodBase methodBase = stackFrame.GetMethod();
            Object[] attributes = methodBase.GetCustomAttributes(
                                      typeof(TestAttribute), false); 
            if (attributes.Length >= 1)
            {
                return methodBase.Name;
            }
        }
        return "Not called from a test method";  
    }
}
    
ответ дан The Light 16.03.2012 в 10:58
источник
  • обратите внимание, что в версиях Release это иногда не работает - метод проверки может быть встроен, и вы не сможете увидеть TestAttribute –  imaximchuk 05.10.2017 в 01:18
0

Если вы не используете Nunit или какой-либо другой сторонний инструмент. вы не получите TestAttribute .

Итак, вы можете сделать это, чтобы получить имя метода тестирования. Используйте TestMethodAttribute для TestAttribute .

    public string GetTestMethodName()
    {
            // for when it runs via Visual Studio locally
            var stackTrace = new StackTrace();
            foreach (var stackFrame in stackTrace.GetFrames())
            {
                MethodBase methodBase = stackFrame.GetMethod();
                Object[] attributes = methodBase.GetCustomAttributes(typeof(TestMethodAttribute), false);
                if (attributes.Length >= 1)
                {
                    return methodBase.Name;
                }
            }
            return "Not called from a test method";
    }
    
ответ дан Jay Patel 29.09.2015 в 12:45
источник