Какой смысл так писать тесты?
От: AlexNek  
Дата: 23.10.12 20:40
Оценка:
Столкнулся с кодом одной известной фирмы и ничего не понял, какой смысл в подобной конструкции?

 [TestFixture]
  public class ...Test : ...TestBase
  {

    [Test]
    public void test001()
    {
      this.DoNamedTest();
    }

    [Test]
    public void test002()
    {
      this.DoNamedTest();
    }

    [Test]
    public void test003()
    {
      this.DoNamedTest();
    }

Имплентацию методов один раз случайно удалось найти, но если искать специально найти почти невозможно, подобных имен море. (Второй раз так и не нашел )
Ладно хочется иметь универсальный запускатель, но отчего бы не сделать его "невидимым", поставив на первое место код для теста.
Ради интереса подсчитал также сколько базовых классов в иерархии. Никогда не поверите — 11 + интерфейс и генерики.

Что я пропустил из новых веяний в тестировании?
Cообщение написано в << RSDN@Home 1.2.0 alpha 5-AN-R8 rev. 13227>>
Re: Какой смысл так писать тесты?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.10.12 08:05
Оценка: +1
Здравствуйте, AlexNek, Вы писали:

AN>Что я пропустил из новых веяний в тестировании?


Навигацию по коду в Студии, Решарпере или декомпиляторе?

А цели могут быть разные. Вряд ли кто-то стал бы городить огород без причин. Проще всего спросить у тех кто уже давно в конторе.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Какой смысл так писать тесты?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 24.10.12 11:23
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Столкнулся с кодом одной известной фирмы и ничего не понял, какой смысл в подобной конструкции?


Как я понимаю, ты смотришь на код РеШарпера.

1) Тестирующий метод лежит как правило рядышком, в этом же классе. В крайнем редком случае — в прямом родителе.
2) Все данные лежат в файлах в отдельном каталоге. Их имена вытаскиваются по рефлексии
3) Такой подход позволяет быстро и эффективно протестировать систему на большом наборе входных данных
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[2]: Какой смысл так писать тесты?
От: AlexNek  
Дата: 24.10.12 22:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, AlexNek, Вы писали:


AN>>Что я пропустил из новых веяний в тестировании?


VD>Навигацию по коду в Студии, Решарпере или декомпиляторе?

Потрясная идея, как это я раньше до этого не додумался?
Может еще поясните как навигировать по "косвенным" вызовам ?


VD>А цели могут быть разные. Вряд ли кто-то стал бы городить огород без причин. Проще всего спросить у тех кто уже давно в конторе.

Спросить то можно только никто видимо не ответит. Код находится в виде ДЛЛ в свободном доступе на сервере.
Вообще то вопрос лежит немного шире.

Нафига писать тесты которые нужно отлаживать не меньше самого приложения и в которых не разобраться "без пол литры"?
Можно ли сказать глядя на этот код, что именно он тестирует? Ну или хотя бы отличия первого теста от второго?

Обычно по тестам можно достаточно быстро разобраться какие действия нужно делать для той или иной задачи. Это если код незнакомый. А для своего кода удобно знать что же там тестер хотел протестировал и отчего тест "вылетает".
Cообщение написано в << RSDN@Home 1.2.0 alpha 5-AN-R8 rev. 13227>>
Re[2]: Какой смысл так писать тесты?
От: AlexNek  
Дата: 24.10.12 22:03
Оценка:
Здравствуйте, xvost, Вы писали:

X>Здравствуйте, AlexNek, Вы писали:


AN>>Столкнулся с кодом одной известной фирмы и ничего не понял, какой смысл в подобной конструкции?


X>Как я понимаю, ты смотришь на код РеШарпера.

Ух ты , а как догадались, тоже плагин писали?
Вообще то не хотелось указывать "автора", но раз и так знают
v7.0\SDK\Bin\JetBrains.ReSharper.Refactorings.Test.CSharp.dll
class CSharpAbstract2InterfaceTest

X>1) Тестирующий метод лежит как правило рядышком, в этом же классе. В крайнем редком случае — в прямом родителе.

ни там ни там не нашел
X>2) Все данные лежат в файлах в отдельном каталоге. Их имена вытаскиваются по рефлексии
то бишь их просто нет при загрузке SDK.
X>3) Такой подход позволяет быстро и эффективно протестировать систему на большом наборе входных данных
Ну вот в этом примере еще как то можно понять, что тут хотели засунуть побольше данных. Хотя тоже нужно знать где и что искать.
        [Test, TestCaseSource("ConvertToSourceDataItem")] 
        public virtual object ConvertToWithDataItem(object testDatas, bool valid, Type toType)
        {
            DataItem dataItem = new DataItemIdentificationNumber((int)testDatas, valid, new DataItemCategory(1, "Test"));         
            return testObject.ConvertTo(null, new CultureInfo("en-EN",false), dataItem, toType); 
        }


А вот как подобная запись может этому способствовать никак не пойму
    public void test001()
    {
      this.DoNamedTest();
    }

Тем более, что где то встречал функцию с именем test001, но с тестирующим кодом без какого либо набора входных данных.

Вообще после некоторого изучения длл-ок пришел к выводу что стиль написания можно назвать ooh oop. Все в классическом классовом подходе, но понять, как все работает довольно непросто. Думал, что вот наконец не будет проблем с настройками — есть даже специальный пример, и все по идее должно быть весьма просто. Ан нет, там тоже есть "ньюансы".
Cообщение написано в << RSDN@Home 1.2.0 alpha 5-AN-R8 rev. 13227>>
Re[3]: Какой смысл так писать тесты?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 25.10.12 09:27
Оценка:
Здравствуйте, AlexNek, Вы писали:

X>>Как я понимаю, ты смотришь на код РеШарпера.

AN>Ух ты , а как догадались, тоже плагин писали?

Вообще-то я один из авторов РеШарпера

X>>1) Тестирующий метод лежит как правило рядышком, в этом же классе. В крайнем редком случае — в прямом родителе.

AN>ни там ни там не нашел

Плохо искал

X>>2) Все данные лежат в файлах в отдельном каталоге. Их имена вытаскиваются по рефлексии

AN>то бишь их просто нет при загрузке SDK.

Ес-но! Кто-ж нашу тестовую базу наружу-то отдаст.

X>>3) Такой подход позволяет быстро и эффективно протестировать систему на большом наборе входных данных

AN>А вот как подобная запись может этому способствовать никак не пойму

Во-первых, надо понять что в РеШарпере практически нет юнит-тестов в чистом виде. Почти все тесты — поведенчские, т.е. для их запуска надо поднять и проинициализиорвать весь движок. Эти и обусловлено все происходящее.

AN>Вообще после некоторого изучения длл-ок пришел к выводу что стиль написания можно назвать ooh oop. Все в классическом классовом подходе, но понять, как все работает довольно непросто. Думал, что вот наконец не будет проблем с настройками — есть даже специальный пример, и все по идее должно быть весьма просто. Ан нет, там тоже есть "ньюансы".


Конечно. И продукт сложный, и предметная область сильно непростая.
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[4]: Какой смысл так писать тесты?
От: AlexNek  
Дата: 25.10.12 21:59
Оценка:
Здравствуйте, xvost, Вы писали:

X>Здравствуйте, AlexNek, Вы писали:


X>>>Как я понимаю, ты смотришь на код РеШарпера.

AN>>Ух ты , а как догадались, тоже плагин писали?

X>Вообще-то я один из авторов РеШарпера

Ну, никак не ожидал повстречать тут, раздел JetBrains скорее мертв чем жив.
Зато хоть есть кому сказать спасибо , просто не представляю как можно теперь работать без решарпера.
В общем, респект и уважуха.

Хотя, пока я был простым пользователем, меня волновал только один вопрос — когда же наконец студия перестанет падать от решарпера.
Теперь же, когда решился написать плагин к нему, пришлось изучать внутренности, так как почитать практически нечего. Но "концепт" самому выловить весьма непросто, да и еще без решарпера

X>>>1) Тестирующий метод лежит как правило рядышком, в этом же классе. В крайнем редком случае — в прямом родителе.

AN>>ни там ни там не нашел

X>Плохо искал

В самом классе имеются функции от test001() до test013()
в базовом всего одна функция protected override ConvertTestBase.TestExecutor CreateTestExecuter() выдающая Abstract2InterfaceWorkflow. (Но Workflow я и так давно нашел и через него так и не удалось отследить всю цепочку)

Меня же интересовали тесты типа этого. Хотя из него также не следует что именно так и следует добавлять folder, однако есть хоть какая то отправная точка.
        [Test]
        public void AddFolder()
        {
            base.RunGuarded(delegate {
                ISolution solution;
                using (base.Locks.UsingWriteLock())
                {
                    solution = this.SolutionManager.OpenExistingSolution(new FileSystemPath(base.CopyTestDataDirectoryToTemp("addFolder")).Combine("addFolder.sln"));
                }
                try
                {
                    IProject project = solution.GetProjectByName("ClassLibrary1");
                    using (IProjectModelTransactionCookie cookie = solution.CreateTransactionCookie(DefaultAction.Commit, "Test", NullProgressIndicator.Instance))
                    {
                        cookie.AddFolder(project, "NewFolder1", null);
                    }
                    base.ExecuteWithGold(delegate (TextWriter writer) {
                        solution.Dump(writer);
                    });
                }
                finally
                {
                    this.SolutionManager.CloseSolution(solution);
                }
            });
        }
        
    protected TestFailureException ExecuteWithSpecifiedGold(FileSystemPath goldPath, [InstantHandle] Action<TextWriter> test, Func<string, string, bool> goldLineEqualsFunc = null, Encoding encoding = null)
    {
      encoding = encoding ?? BaseTestNoShell.ourUtf8WithBomEncoding;
      byte[] testData;
      using (MemoryStream memoryStream = new MemoryStream())
      {
        using (StreamWriter streamWriter = new StreamWriter((Stream) memoryStream, encoding))
          test((TextWriter) streamWriter);
        testData = memoryStream.ToArray();
      }
      TestFailureException result;
      try
      {
        result = TestUtil.CheckDataAgainstGoldFile(testData, goldPath, this.FailTestIfCheckFails, encoding, goldLineEqualsFunc ?? TestUtil.GetCompareStringsFunction(true));
      }


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

X>>>2) Все данные лежат в файлах в отдельном каталоге. Их имена вытаскиваются по рефлексии

AN>>то бишь их просто нет при загрузке SDK.

X>Ес-но! Кто-ж нашу тестовую базу наружу-то отдаст.

В принципе тестовая база для разработки плагина особо и не нужна. Все равно прийдется под него все свое писать.

X>>>3) Такой подход позволяет быстро и эффективно протестировать систему на большом наборе входных данных

AN>>А вот как подобная запись может этому способствовать никак не пойму

X>Во-первых, надо понять что в РеШарпере практически нет юнит-тестов в чистом виде. Почти все тесты — поведенчские, т.е. для их запуска надо поднять и проинициализиорвать весь движок. Эти и обусловлено все происходящее.

Тяжело как то было это представить, тем более что все же попадаются.
Но кажется, что при подобных условиях можно было сделать что то типа следующего кода, а не городить гору базовых классов. Просто видимо никто об этом не задумывался. Кому требовалось иметь "понятные" тесты — главное что бы работало.

...
engine.Init()
...
[Test]
public void MoveOnePublicFunction()
{
  testfile = OpenTestFile("abc.cs");
  testAction = ....
  expected =...
  engine.DoTest(testFile,testAction,expected);
}


AN>>Вообще после некоторого изучения длл-ок пришел к выводу что стиль написания можно назвать ooh oop. Все в классическом классовом подходе, но понять, как все работает довольно непросто. Думал, что вот наконец не будет проблем с настройками — есть даже специальный пример, и все по идее должно быть весьма просто. Ан нет, там тоже есть "ньюансы".


X>Конечно. И продукт сложный, и предметная область сильно непростая.

Что то создается впечатление, что некоторые вещи сделаны уж слишком сложно, в угоду какого то "правильного" концепта.
А некоторые используются как то не так, как ожидается.

Ну например, я ожидал, что если "дать" Solution-у визитор, то VisitProject(IProject project) обойдет все проекты,
VisitProjectItem обойдет файлы, еще что то обойдет описанные типы и т.п.

А если создать ProgressIndicator "по примерам", должно что то показываться.

Хотя что то я отдалился от темы, все же в этой теме интересовали мнения как следует писать тесты для сложных систем. Но видимо это мало кому неинтересно.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R8 rev. 13227&gt;&gt;
Re[3]: Какой смысл так писать тесты?
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 31.10.12 12:00
Оценка:
AN>Нафига писать тесты которые нужно отлаживать не меньше самого приложения и в которых не разобраться "без пол литры"?
AN>Можно ли сказать глядя на этот код, что именно он тестирует? Ну или хотя бы отличия первого теста от второго?

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

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

Дальше рассказывать?
Re[4]: Какой смысл так писать тесты?
От: AlexNek  
Дата: 01.11.12 11:51
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

AN>>Нафига писать тесты которые нужно отлаживать не меньше самого приложения и в которых не разобраться "без пол литры"?

AN>>Можно ли сказать глядя на этот код, что именно он тестирует? Ну или хотя бы отличия первого теста от второго?

EOH>Потому что есть ребята, у которых все хорошо получаются. Иногда они собираются с силами и делают презентации и выступления, где пытаются рассказать что они делают для того, чтобы у них хорошо получалось. Но хорошие тимлиды/менеджеры и хорошие преподаватели — это разные квалификации. Не каждый человек, который умеет хорошо разрабатывать программы, может этому научить других.


EOH>Выступления слушают не только такие же могущие ребята, но и ребята квалификацией пониже. Потом слушатели приходят в свои конторы и рассказывают, что были на мегапрезентации мегаперца, который рассказал как делать по уму. И мегаперец, кроме всего прочего, говорил про юнит тесты...


EOH>Дальше рассказывать?

Не думаю что у них подобная ситуация, скорее напоминает микрософт. "Мы делаем как нам удобно, а вы уж как то приспосабливайтесь".

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

А вообще, кто то еще здесь интересуется разработкой плагинов для решарпера? Хотя бы чисто для своих нужд.
Cообщение написано в &lt;&lt; RSDN@Home 1.2.0 alpha 5-AN-R8 rev. 13227&gt;&gt;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.