Многие наши системные тесты написаны в стиле BDD, и мы прилично используем унаследованные поведения для минимизации дублирования, например, это может быть базовая иерархия для тестов на покупку.
class BehavesLikeSuccessfulPurchase
class BehavesLikePurchaseWithValidCreditCard : BehavesLikeSuccessfulPurchase
В этом случае BehavesLikeSuccessfulPurchase
определяет общее поведение, например, в выписке по счету должна быть дебетовая запись, а класс BehavesLikePurchaseWithValidCreditCard
определяет рабочий процесс тестирования для покупки любого типа продукта с действующей кредитной картой, поэтому тесты небольшие. производные классы, которые просто предоставляют конкретный экземпляр продукта, например
[Concern(typeof(Video))]
class WhenPurchasedWithValidCreditCard : BehavesLikePurchaseWithValidCreditCard
Однако, в зависимости от конкретного типа продукта, нам также необходимо провести некоторые дополнительные проверки, например, когда видео успешно приобретено, мы хотим убедиться, что оно добавлено в библиотеку видео пользователя. В идеале это может быть определено другим классом и смешано с использованием гипотетического синтаксиса:
class BehavesLikeSuccessfulVideoPurchase
[Concern(typeof(Video))]
class WhenPurchasedWithValidCreditCard : BehavesLikePurchaseWithValidCreditCard
mixin BehavesLikeSuccessfulVideoPurchase
{
}
Но, конечно, C # не поддерживает множественное наследование или миксины, поэтому мы заканчиваем тем, что пишем множество стандартных методов, которые перенаправляют вызовы на дополнительные поведения, которые должны меняться каждый раз, когда изменяется поведение.
Что нам действительно нужно, так это фреймворк, который имеет свой собственный механизм поддержки множественных поведений из тестов, просто предоставляя тип (ы) дополнительных поведений, которые следует соблюдать. Я смотрел на xUnit и примеры спецификаций, и похоже, что было бы возможно придумать некоторые расширения, которые могли бы помочь, но есть ли что-нибудь уже существующее?