Поблочное тестирование и объем объектов - как протестировать частные/внутренние методы и т.д.?

Ваша тестовая среда ("вручную протестировал сценарий") и cron среда отличается во многих отношениях. Некоторые из этих различий заставляют Ваш python сценарий перестать работать (я надеюсь, что Вы имели в виду #!/usr/bin/python, количества Случая!).

Добавляют это к Вашему crontab в течение нескольких минут, затем удаляют его:

*  *  *   *   *     (echo "=== set ===";set;echo "===env ==="; env | sort;echo "=== alias ===";alias) >cron.environment

кроме того, в Вашем тесте envionment, сделайте:

echo "=== set ===";set;echo "===env ==="; env | sort;echo "=== alias ===";alias) >test.environment

Чтение/разность каждый файл (less {cron,test}.environment;diff {cron,test}.environment).

Read man 5 crontab, чтобы видеть, как измениться cron среда.

Помнят, cron не bash, но сценарии обертки удара составляют fo это.

5
задан Evgeny 2 September 2009 в 00:22
поделиться

10 ответов

Вы можете сделать внутренние компоненты видимыми для определенных сборок с помощью InternalsVisibleToAttribute .

2
ответ дан 13 December 2019 в 19:31
поделиться

Думаю, это зависит от вашего представления о том, что такое модуль, верно? Я обычно пишу модульные тесты для доступного интерфейса и игнорирую личные вещи. Я работал с людьми, которые будут защищать личные вещи (java) для доступа к модульным тестам.

4
ответ дан 13 December 2019 в 19:31
поделиться

i просто протестируйте общедоступные методы (и нет, меня не интересуют метрики покрытия, меня интересуют работающие функции).

обратите внимание, что если общедоступные методы не используют внутренние методы, то внутренние методы не должны существовать !

3
ответ дан 13 December 2019 в 19:31
поделиться

Вот хорошая статья по этой теме:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

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

2
ответ дан 13 December 2019 в 19:31
поделиться

Многие люди скажут, что вам не следует тестировать внутренние методы, а вместо этого тестировать их через общедоступный API. Тем не менее, вы можете использовать отражение, если действительно хотите получить доступ к этим закрытым членам.

1
ответ дан 13 December 2019 в 19:31
поделиться

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

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

1
ответ дан 13 December 2019 в 19:31
поделиться

Visual Studio может сгенерировать для вас частные аксессоры. Ознакомьтесь с Модульными тестами для частных, внутренних и дружественных методов на MSDN. Я считаю, что VS2005 просто сгенерировал и добавил к вашему проекту модульного тестирования частные классы доступа. Так что вам пришлось регенерировать их, когда все изменилось. Однако VS2008 создает частную сборку средств доступа и делает ее доступной для проекта модульного тестирования. Вы используете NUnit, но я думаю, что все должно быть в порядке. Проверить это. Таким образом, вы можете защитить свой реальный код от кода, связанного с тестированием и / или взломов.

0
ответ дан 13 December 2019 в 19:31
поделиться

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

Я также создал частичные классы для тестирования частных методов и использовал директиву компилятора для всей части (которая находилась в отдельном файле). Опять же, я не говорю, что это лучший вариант, но иногда вам нужно двигаться вперед.

Во время сборки мы могли запускать модульные тесты в режиме отладки или выпуска, и при желании мы могли вырезать тестовый код из любой сборки, так что было отсутствие вреда при сопоставлении тестового кода с тестируемым кодом; во всяком случае, он похож по аргументу на code-and-data-together = object или object-and-doc-comments = документированный-объект. Другими словами:

0
ответ дан 13 December 2019 в 19:31
поделиться

Для этого я использовал несколько методов. Я сделал свои частные методы защищенными, чтобы я мог наследовать от класса в моем модульном тесте и создать «вспомогательный» класс для тестирования этих методов. Другой - отражение. Отражение проще IMO, но противоречит тому, как ваши классы должны быть разработаны для тестирования. Вот упрощенная версия того, о чем я говорю.

public static class ReflectionHelper
{
    public static object RunStaticMethod<TInstance>(string methodName, params object[] methodParams)
    {
        var methodType = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
        return RunMethod<TInstance>(null, methodName, methodType, methodParams);
    }

    public static object RunInstanceMethod<TInstance>(this TInstance instance, string methodName, params object[] methodParams)
    {
        var methodType = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        return RunMethod<TInstance>(instance, methodName, methodType, methodParams);
    }

    private static object RunMethod<TInstance>(object instance, string methodName, BindingFlags methodType, params object[] methodParams)
    {
        var instanceType = typeof(TInstance);
        var method = instanceType.GetMethod(methodName, methodType);
        if (method == null)
        {
            throw new ArgumentException(string.Format("There is no method '{0}' for type '{1}'.", methodName, instanceType));
        }

        var result = method.Invoke(instance, methodParams);

        return result;
    }
}

Для такого класса, как этот

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    internal string GetPrettyName()
    {
        return string.Concat(FirstName, " ", LastName);
    }

    static internal int GetSystemId(string userName)
    {
        // some magic here
        return 13;
    }
}

Вы бы использовали их так

var user = new User { FirstName = "Peter", LastName = "Gibbons" };

var name = user.RunInstanceMethod("GetPrettyName");
Assert.That(name, Is.EqualTo("Peter Gibbons"));

var id = ReflectionHelper.RunStaticMethod<User>("GetSystemId", "tester");
Assert.That(id, Is.EqualTo(13));
0
ответ дан 13 December 2019 в 19:31
поделиться

Мне нравится помещать свои модульные тесты в тот же класс, что и тот, который они тестируют. У этого есть два преимущества: первое состоит в том, что он решает проблему, с которой вы сталкиваетесь, второе - вы никогда не теряете и не забываете о них, как это часто бывает, если они находятся в отдельной сборке.

Не все согласны с такого рода подход (см. этот вопрос SO , который я задавал ранее), но пока я не нашел или не указал мне на какие-либо недостатки. Я проводил модульные тесты таким образом уже 4 или 5 лет.

#if UNITTEST
using NUnit.Framework;
#endif

public class MyBlackMagic
{
    private int DoMagic()
    {
        return 1;
    }

    #if UNITTEST

    [TestFixture]
    public class MyBlackMagicUnitTest
    {
         [TestFixtureSetUp]
         public void Init()
         {
             log4net.Config.BasicConfigurator.Configure();
         }

         [Test]
         public void DoMagicTest()
         {
             Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
             Assert.IsTrue(DoMagic() == 1, "You are not a real magician!");
         }
     }

     #endif
 }
-2
ответ дан 13 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: