|
1 |
| -ConventionTests |
2 |
| -=============== |
| 1 | +TestStack.ConventionTests |
| 2 | +========================= |
3 | 3 |
|
4 | 4 | ### What is ConventionTests?
|
5 |
| -Convention over Configuration is a great way to cut down repetitive boilerplate code. But how do you validate that your code adheres to your conventions? Convention Tests is a code-only NuGet that provides a simple API to build validation rules for convention validation tests. |
| 5 | +Convention over Configuration is a great way to cut down repetitive boilerplate code. |
| 6 | +But how do you validate that your code adheres to your conventions? |
| 7 | +TestStack.ConventionTests is a simple NuGet library that makes it easy to build validation rules for convention validation tests. |
6 | 8 |
|
7 |
| -### Using ConventionTests |
8 |
| -ConventionTests is a simple code-only Nuget that provides a minimalistic and limited API enforcing certain structure when writing convention tests and integrating with NUnit. Installing it will add two .cs files to the project and a few dependencies ([NUnit](http://www.nunit.org/), [Castle Windsor](http://stw.castleproject.org/Windsor.MainPage.ashx) and [ApprovalTests](http://approvaltests.sourceforge.net/)). |
9 |
| - |
10 |
| -ConventionTests.NUnit file is where all the relevant code is located and __Run file is the file that runs your tests. The approach is to create a file per convention and name them in a descriptive manner, so that you can learn what the conventions you have in the project are by just looking at the files in your Conventions folder, without having to open them. |
11 |
| - |
12 |
| -Each convention test inherits (directly or indirectly) from the IConventionTest interface. There’s an abstract implementation of the interface, ConventionTestBase and a few specialized implementations for common scenarios provided out of the box: Type-based one (ConventionTest) and two for Windsor (WindsorConventionTest, non-generic and generic for diagnostics-based tests). |
| 9 | +TestStack.ConventionTests also will generate a convention report of the conventions present in your codebase, which you can publish as **living documentation** |
13 | 10 |
|
14 |
| -#### Type-based convention tests |
15 |
| -The most common and most generic group of conventions are ones based around types and type information. Conventions like “every controller’s name ends with ‘Controller’”, or “Every method on WCF service contracts must have OperationContractAttribute” are examples of such conventions. |
16 |
| - |
17 |
| -You write them by creating a class inheriting ConventionTest, which forces you to override one method. Here’s a minimal example |
| 11 | +### Using ConventionTests |
18 | 12 |
|
19 |
| - public class Controllers_have_Controller_suffix_in_type_name : ConventionTest |
| 13 | + [Test] |
| 14 | + public void DomainHasVirtualMethodsConvention() |
20 | 15 | {
|
21 |
| - protected override ConventionData SetUp() |
22 |
| - { |
23 |
| - return new ConventionData |
24 |
| - { |
25 |
| - Types = t => t.IsConcrete<IController>(), |
26 |
| - Must = t => t.Name.EndsWith("Controller") |
27 |
| - }; |
28 |
| - } |
| 16 | + // Define some data |
| 17 | + var nHibernateEntities = Tpes.InAssemblyOf<SampleDomainClass>() |
| 18 | + .ConcreteTypes().InNamespace(typeof (SampleDomainClass).Namespace) |
| 19 | + .ToTypes("nHibernate Entitites"); |
| 20 | + |
| 21 | + // Apply convention to data |
| 22 | + Convention.Is(new AllMethodsAreVirtual(), nhibernateEntities); |
29 | 23 | }
|
30 | 24 |
|
31 |
| -#### Windsor-based convention tests |
32 |
| -Another common set of convention tests are tests regarding an IoC container. Castle Windsor is supported out of the box. The structure of the tests and API is similar, with the difference being that instead of types we’re dealing with Windsor’s component Handlers. |
| 25 | +For more information [view the TestStack.ConventionTests documentation](http://docs.teststack.net/conventiontests/index.html) |
33 | 26 |
|
34 |
| - public class List_classes_registered_in_Windsor : WindsorConventionTest |
35 |
| - { |
36 |
| - protected override WindsorConventionData SetUp() |
37 |
| - { |
38 |
| - return new WindsorConventionData(new WindsorContainer() |
39 |
| - .Install(FromAssembly.Containing<AuditedAction>())) |
40 |
| - { |
41 |
| - FailDescription = "All Windsor components", |
42 |
| - FailItemDescription = h => BuildDetailedHandlerDescription(h)+" | "+ |
43 |
| - h.ComponentModel.GetLifestyleDescription(), |
44 |
| - }.WithApprovedExceptions("We just list all of them."); |
45 |
| - |
46 |
| - } |
47 |
| - } |
| 27 | +### Packaged Conventions |
| 28 | +Here is a list of some of the pacakged conventions |
48 | 29 |
|
49 |
| -#### Custom convention tests |
50 |
| -Say we wanted to create a convention test that lists all of our NHibernate collections where we do cascade deletes, so that when we add a new collection the test would fail reminding us of the issue, and force us to pay attention to how we structure relationships in the application. To do this we could create a base NHibernateConventionTest and NHiibernateConventionData to create similar structure, or just build a simple one-class convention like that: |
| 30 | + - **AllClassesHaveDefaultConstructor** - All classes in defined data must have a default ctor (protected or public) |
| 31 | + - **AllMethodsAreVirtual** - All classes in defined data must have virtual methods (includes get_Property/set_Property backing methods) |
| 32 | + - **ClassTypeHasSpecificNamespace** - For example, Dto's must live in the Assembly.Dtos namespace' |
| 33 | + - **FilesAreEmbeddedResources** - All .sql files are embedded resources |
| 34 | + - **ProjectDoesNotReferenceDllsFromBinOrObjDirectories** - Specified project file must not reference assemblies from bin/obj directory |
| 35 | + - **MvcControllerNameAndBaseClassConvention** - Enforces MVC controller naming conventions |
| 36 | + - Types ending in *Controller must inherit from Controller (or ApiController), and |
| 37 | + - Types inheriting from ControllerBase must be named *Controller |
| 38 | + - **MvcControllerNameAndBaseClassConvention** - Enforces WebApi controller naming conventions |
| 39 | + - Types ending in *Controller must inherit from ApiController (or Controller), and |
| 40 | + - Types inheriting from ApiController must be named *Controller |
51 | 41 |
|
52 |
| - public class List_collection_that_cascade_deletes:ConventionTestBase |
53 |
| - { |
54 |
| - public override void Execute() |
55 |
| - { |
56 |
| - // NH Bootstrapper is our custom class to set up NH |
57 |
| - var bootstrapper = new NHibernateBootstrapper(); |
58 |
| - var configuration = bootstrapper.BuildConfiguration(); |
59 |
| - |
60 |
| - var message = new StringBuilder("Collections with cascade delete orphan"); |
61 |
| - foreach (var @class in configuration.ClassMappings) |
62 |
| - { |
63 |
| - foreach (var property in @class.PropertyIterator) |
64 |
| - { |
65 |
| - if(property.CascadeStyle.HasOrphanDelete) |
66 |
| - { |
67 |
| - message.AppendLine(@class.NodeName + "." + property.Name); |
68 |
| - } |
69 |
| - } |
70 |
| - } |
71 |
| - Approve(message.ToString()); |
72 |
| - } |
73 |
| - } |
| 42 | +If you would like to define your own conventions see [Defining Conventions](http://docs.teststack.net/ConventionTests/DefiningConventions.html) |
74 | 43 |
|
75 | 44 | ### Where to find out more
|
76 |
| -[Krzysztof Koźmic](https://github.com/kkozmic) spoke about ConventionTests at NDC 2012. You can find the video of that talk [here](http://vimeo.com/43676874), slides [here](http://kozmic.pl/presentations/) and the introductory blog post [here](http://kozmic.pl/2012/06/14/using-conventiontests/). |
| 45 | +[Krzysztof Koźmic](https://github.com/kkozmic) spoke about ConventionTests at NDC 2012. You can find the video of that talk [here](http://vimeo.com/43676874), slides [here](http://kozmic.pl/presentations/) and the introductory blog post [here](http://kozmic.pl/2012/06/14/using-conventiontests/). |
| 46 | + |
| 47 | +[TestStack.ConventionTests documentation](http://docs.teststack.net/conventiontests/index.html) |
0 commit comments