Coder Social home page Coder Social logo

naturalspec's Introduction

NaturalSpec is based on NUnit and completely written in F# - 
but you don't have to learn F# to use it.

== Tutorials ==

* http://bit.ly/aKmLMx - Introducing NaturalSpec
* http://bit.ly/rNIsm - "Getting started" with NaturalSpec
* http://bit.ly/aBS5db - Using NaturalSpec to create a spec for C# projects
* http://bit.ly/8ZtTTe - Mocking objects with NaturalSpec
* http://bit.ly/aqDrUj - Parameterized Scenarios with NaturalSpec
* http://bit.ly/ao3pAB - Testing Quicksort with NaturalSpec

== Samples ==

You can write your spec mostly in natural language like in the following samples:

=== Sample 1 - Collections ===

[<Scenario>]
let ``When removing an element from a list it should not contain the element``() =
  Given [1;2;3;4;5]                 // "Arrange" test context
    |> When removing 3              // "Act"
    |> It shouldn't contain 3       // "Assert"
    |> It should contain 4          // another assertion
    |> It should have (Length 4)    // Assertion for length
    |> It shouldn't have Duplicates // Tests if the context contains duplicates
    |> Verify                       // Verify scenario

When running this sample the output is the following:

Scenario: When removing an element from a list it should not contain the element
  - Given [1; 2; 3; 4; 5]

    - When removing 3
      => It should not contain 3
      => It should contain 4
      => It should have length 4
      => It should not have Duplicates
  ==> OK
  ==> Time: 0.0239s

=== Sample 2 - Math ===

[<Scenario>]
let ``When calculating factorial of 5 it should equal 120``() =
  Given 5
    |> When calculating factorial
    |> It should equal 120
    |> Verify

The output of this sample is:

Scenario: When calculating factorial of 5 it should equal 120
  - Given 5
     - When calculating factorial 
      => It should equal 120
  ==> OK
  ==> Time: 0.0043s

=== Sample 3 - Mocking ===

[<Scenario>]
let ``When selling a car for 30000 it should equal the DreamCar mocked``() =
  As Bert
    |> Mock Bert.SellCar 30000 DreamCar
    |> When selling_a_car_for 30000
    |> It should equal DreamCar
    |> Verify

The output of this sample is:

Scenario: When selling a car for 30000 it should equal the DreamCar mocked
  - As Bert
     - With mocking
     - When selling a car for 30000
      => It should equal BMW (200 HP)
      => It should not equal Fiat (45 HP)
  ==> OK
  ==> Time: 0.0062s

Read more about "http://bit.ly/8ZtTTe - Mocking objects with NaturalSpec".


=== Sample 4 - Expected Failures ===

You can use the Attribute "Fail", "Fail_with" and "Fail_with_type" if you want a specific scenario to fail:

[<Scenario>]
[<Fails_with_type (typeof<DivideByZeroException>)>]
let ``When dividing by zero it should fail``() =
  Given 10
    |> When dividing_by 0
    |> Verify

[<Scenario>]
[<Fails_with "My error">]
let ``When raising exception``() =
  Given 0
    |> When raising "My error"
    |> Verify

The output would look like:

Scenario: When dividing by zero it should fail
  - Should fail with exception type System.DivideByZeroException

  - Given 10
     - When dividing by 0

Scenario: When raising exception
  - Should fail with "My error"
  - Given 0
     - When raising exception "My error"
     
=== Sample 5 - ScenarioTemplates ===

It is possible to use templates for scenarios:

// with Example attribute
[<Example(1, 1)>]  
[<Example(5, 120)>]
[<Example(10, 3628800)>]
let ``When calculating fac``(x,result) =
  Given x
    |> When calculating factorial
    |> It should equal result
      |> Verify

This code creates 3 scenarios and the output would look like:

Scenario: When calculating fac 
  - Given 1
     - When calculating factorial 
      => It should equal 1
  ==> OK
  ==> Time: 0.0292s

Scenario: When calculating fac 
  - Given 5
     - When calculating factorial 
      => It should equal 120
  ==> OK
  ==> Time: 0.0064s

Scenario: When calculating fac 
  - Given 10
     - When calculating factorial 
      => It should equal 3628800
  ==> OK
  ==> Time: 0.0058s
  
If you want more flexibility you can use the ScenarioSource attribute:

/// with a scenario source      
let MyTestCases =
  TestWith (tripleParam 12 3 4)
    |> And (tripleParam 12 4 3)
    |> And (tripleParam 12 6 2)
    |> And (tripleParam 0 0 0)    
        |> ShouldFailWith (typeof<System.DivideByZeroException>)
    |> And (tripleParam 1200 40 30)

[<ScenarioSource "MyTestCases">]
let ``When dividing`` a b result =
 Given a 
   |> When dividing_by b
   |> It should equal result
   |> Verify

Read more about "http://bit.ly/aqDrUj - Parameterized Scenarios with NaturalSpec".

naturalspec's People

Contributors

forki avatar pocketberserker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

naturalspec's Issues

Removed Mock Features?

It took me way too long to start playing around with this, but it looks like the project has a TON of potential as an all in one testing solution for F#.

I'm a big fan of MOQ for my C# code, but it won't work in F# without some extra ugliness as it relies on Linq Expressions. One of the things that finally made me start playing around with NaturalSpec was the clean syntax for mocking that you used to support. It fit my needs perfectly, but it looks like it was removed about a month ago. Is this just to avoid a dependency on Rhino.Mocks, or is there something else in the works?

Either way, I'd like to propose supporting the old syntax (or something similar) since the mocking features that replaced it don't meet my needs. I'd be happy to help implement these features, and I'd rather work with similar goals instead of diverging.

Let me know what your thoughts are.

-Chris

Build fails on tests

When running build.bat, the project is built, but the test target fails:
...
Time Elapsed 00:00:03.10
Building project: .\src\test\Spec.Euler\Spec.Euler.fsproj
c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe .\src\test\Spec.Euler\Spec.Euler.fsproj /target:Build /p:Configuration=Debug /p:OutputPath=".\test"
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.1]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 6/20/2010 8:35:24 PM.
Project ".\src\test\Spec.Euler\Spec.Euler.fsproj" on node 1 (Build target(s)).
PrepareForBuild:
Creating directory "obj\Debug".
Creating directory "bin\Debug".
Project ".\src\test\Spec.Euler\Spec.Euler.fsproj" (1) is building ".\src\app\NaturalSpec\NaturalSpec.fsproj" (2) on node 1 (default targets).
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
NaturalSpec -> .\test\NaturalSpec.dll
Done Building Project ".\src\app\NaturalSpec\NaturalSpec.fsproj" (default targets).
CoreCompile:
......\tools\FSharp\fsc.exe -o:obj\Debug\Spec.Euler.dll -g --debug:full --noframework --define:DEBUG --define:TRACE
--doc:bin\Debug\Spec.Euler.XML --optimize- --tailcalls- -r:.\tools\FSharp\FSharp.Core.dll -r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll -r:.\test\NaturalSpec.dll -r:.\tools\Nunit\nunit.framework.dll -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" -r:"C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2521.0\Net35\System.CoreEx.dll" -r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll -r:"C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2521.0\Net35\System.Interactive.dll" -r:"C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2521.0\Net35\System.Reactive.dll"
-r:"C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2521.0\Net35\System.Threading.dll" -r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll --target:library --warn:3 --warnaserror:76 --fullpaths --flaterrors Memoization.fs MathHelper.fs StringHelper.fs Problem1.fs Problem2.fs Problem3.fs Problem4.fs Problem5.fs Problem6.fs Problem7.fs Problem8.fs Problem9.fs Problem10.fs Problem11.fs Problem12.fs Problem13.fs Problem14.fs Problem15.fs Problem16.fs Problem17.fs Problem18.fs Problem19.fs Problem20.fs Problem21.fs Problem22.fs Problem23.fs Problem25.fs Problem26.fs Problem30.fs Problem31.fs Problem48.fs Problem52.fs Problem53.fs Problem59.fs Problem67.fs Problem77.fs

.\src\test\Spec.Euler\Problem19.fs(4,12): error FS1108: The type 'System.IObservable`1' is required here and is unavailable. You must add a reference to assembly 'System.Observable, Version=1.0.0.102, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. [.\src\test\Spec.Euler\Spec.Euler.fsproj]

.\src\test\Spec.Euler\Problem19.fs(13,30): error FS0039: The type 'DateTime' is not defined [.\src\test\Spec.Euler\Spec.Euler.fsproj]

.\src\test\Spec.Euler\Problem19.fs(13,57): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]

.\src\test\Spec.Euler\Problem19.fs(18,31): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]

.\src\test\Spec.Euler\Problem19.fs(18,45): error FS0039: The namespace or module 'DayOfWeek' is not defined [.\src\test\Spec.Euler\Spec.Euler.fsproj]

.\src\test\Spec.Euler\Problem19.fs(18,65): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]
Done Building Project ".\src\test\Spec.Euler\Spec.Euler.fsproj" (Build target(s)) -- FAILED.

Build FAILED.

".\src\test\Spec.Euler\Spec.Euler.fsproj" (Build target) (1) ->
(CoreCompile target) ->
.\src\test\Spec.Euler\Problem19.fs(4,12): error FS1108: The type 'System.IObservable`1' is required here and is unavailable. You must add a reference to assembly 'System.Observable, Version=1.0.0.102, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. [.\src\test\Spec.Euler\Spec.Euler.fsproj]
.\src\test\Spec.Euler\Problem19.fs(13,30): error FS0039: The type 'DateTime' is not defined [.\src\test\Spec.Euler\Spec.Euler.fsproj]
.\src\test\Spec.Euler\Problem19.fs(13,57): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]
.\src\test\Spec.Euler\Problem19.fs(18,31): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]
.\src\test\Spec.Euler\Problem19.fs(18,45): error FS0039: The namespace or module 'DayOfWeek' is not defined [.\src\test\Spec.Euler\Spec.Euler.fsproj]
.\src\test\Spec.Euler\Problem19.fs(18,65): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved. [.\src\test\Spec.Euler\Spec.Euler.fsproj]

0 Warning(s)
6 Error(s)

Time Elapsed 00:00:04.85
Running build failed.
Error:
Building .\src\test\Spec.Euler\Spec.Euler.fsproj project failed.


Build Time Report

Target Duration


Clean 00:0Fak0:00.0196836
BuildApp 00:00:07.3118153
Total: 00:00:29.7322913
------------e.---Ta-r----ge---t-H--e-l--p-e--r-+--B-u--i-l--d-E--r-r--o-r--:- --S-t-o-p---p-e--d- --b-u--i-l
d! Error occured in target "BuildTest".
Message: Building C:\Users\ryan\dev\NaturalSpec\src\test\Spec.Euler\Spec.Euler.fsproj project failed.
at [email protected](BuildError exn)
at Microsoft.FSharp.Primitives.Basics.List.iter[T](FSharpFunc2 f, FSharpList1 x)
at Microsoft.FSharp.Collections.ListModule.Iterate[T](FSharpFunc2 action, FSharpList1 list)
at Fake.TargetHelper.run(String targetName)
at [email protected](String targetName)
at <StartupCode$FSI_0001>.$FSI_0001.main@() in C:\Users\ryan\dev\NaturalSpec\build.fsx:line 90
Stopped due to error
Press any key to continue . . .

Build on Mono

The paths with backslash are not mono-friendly, and nunit from mono is not invoked properly.

Re-Check the samples in the readme

FYI:

I was recently trying to evaluate the project and copy/pasting the samples from the readme I noticed that some of the assertions in the first sample don't compile due to a possible case change in the project

(Length 4) should be (length 4)
Duplicates should be duplicates.

Build on Mono

The paths with backslash are not mono-friendly, and nunit from mono is not invoked properly.

Exception in multiple mockery instanciation of the same type

Hi.

I'd like to try unit-testing with mocks in F# as well as other .NET languages,
and your library looks powerful and so cool.

But I came across a problem on an elementary program as following.

When I try to create 2 mock instances of the same type,
it throws System.ArgumentException with a message
such as "An item is already added that contains same key".

I'm sorry but the message is not accurate because it was translated to my mother language...

What shall I do to make multiple mockery-instanciation work?

Karak

-- code for reproduction
#light
module MultipleInstanciation

open NaturalSpec

type IFoo = interface
  end

let binaryFunc (foo1: IFoo) (foo2: IFoo) : unit = ()

type FooImpl = class
  new() = {}
    interface IFoo
  end

[<Scenario>]
let ``try to create 2 mock-instance``() =
  let foo1 = mock<IFoo> "mock1"
  let foo2 = mock<IFoo> "mock2" // throw Exception!
  //let foo2 = new FooImpl ()

  Given foo2
    |> When calculating binaryFunc foo1
    |> Verify

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.