Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Wednesday, 15 October 2014
# Thursday, 02 October 2014
( Funny )

Version 4 of the jokes website, which started as a demo for some talks on

  • MVC5
  • EF6
  • BDD
  • OO design and Composition
    • Add/Edit Validation
      • Can’t have 2 titles the same
      • Must have a title
      • Title must be > 4 chars
    • ViewModels
      • StoryCreatorResult
  • Responsive design (Bootstrap)
  • Github and Azure deployment.
  • Preferring simple HTML to helpers in views
  • Has now incorporated DI and TDD
  • Migrations (but not all of it..explore more)
  • Service layer with StoryService

Engineering

  • Take current production v3 codebase and merge with new DI and Unit testable codebase
  • Explore Pluralsight for where to go next with v4 codebase
  • Use branches for feature dev?
  • How to name tests – Traits not working well with Resharper test runner
  • Build server / Tests / Deploy to test then prod?
  • A ‘design’ as looking good is important

Exception handling
Logging
Performance of pages – on a per page level, over time

Use Dapper for higher perf on queries

caching – L1-5

Why

Make better apps at work
Make a video?
Speak at user groups?
Speak at conferences

New Features

Drive out features using BDD, explaining the business need.

  • A user has scrolled down the page, and really likes the jokes.  Votes for it, and the page stays where it is
  • A user is on a mobile device, and doesn’t want to have to scroll horizontally to see everything
  • A user remembers seeing a joke about a stick, and wants to easily search for it typing in ‘sti’  and immediately seeing the relevant jokes displayed
  • A user wants to write his own joke into the site, so signs up with a standard email, then can post a joke.
  • When a joke is posted it is checked for rude words
  • A user forgets his password and can have the site send to his email address
  • A user goes to davesjokes.co.uk and www.davesjokes.co.uk and they both work
| | # 
# Wednesday, 02 April 2014
( BDD | Funny )

The third iteration of the British Humour / Funny website

image

image

  • First iteration (shown above – Winter)
    • Generic repository
    • EF CodeFirst
    • Fakes
    • Unity
    • IValidatableObject
  • Second iteration (below - Humour)
    • Based on Imar’s work
    • Heavy
    • Never got it into production

image

What Are We Doing?

  • Webapp to display ‘Stories’ ie jokes/video/quote/pictures/animated gif
  • CRUD form for administrator
  • BDD style of development
  • KISS
    • Real code that I intend to use
    • Not overly complicate

Setup

  • xUnit
  • FluentAssertions
  • GitHub put source onto

Features

Category of things that an application does.  A business critical feature ie not engineering eg Mailers.  Something that’s going to deliver some value

  • Authentication
  • Registration
  • Reminders

Funny:

  • Display
  • CRUD

BDD

  • Feature
  • Scenario (context) – class
  • Spec (test) – method

BDD – Gauging how our application behaves

Unit Testing – Isolated functionality of app returns what is expected

image
Unit test.. not BDD..

image
BDD – What happens when I do this approach.  Specify how the application works in the eyes of a user.

Send tests to manager as a screenshot… Is this what you mean?

‘Should’ ambiguous

[Trait("User visits the Homepage", "")]
public class VisitHomepage {
    [Fact(DisplayName="Show list of Stories in rank order")]
    public void ShowListOfStoriesInRankOrder() {
        throw new NotImplementedException();
    }
    [Fact(DisplayName = "Log entry is created")]
    public void LogEntryIsCreated() {
        throw new NotImplementedException();
    }
}

image
First shot at creating BDD tests for my app.

BDD Philosophy

Dan North in March 2006

..”Programmers wanted to know where to start, what to test and what not to test, how much to test in one go, what to call their tests, and how to understand why a test fails.”

Telling stories with our tests.

Given, When, Then…

as a, i want, so that

what value to end user..test should show

BDD is a user-oriented way to structure tests and organise development

Takes great effort and patience to get right.

Test Naming

[Trait("Anon User visits the Homepage", "")]
public class VisitHomepage {
    [Fact(DisplayName="Show list of all Stories in rank order")]
    public void ShowListOfStoriesInRankOrder() {
        throw new NotImplementedException();
    }
    [Fact(DisplayName = "Log entry is created")]
    public void LogEntryIsCreated() {
        throw new NotImplementedException();
    }
}

Spec (test) name - how our code responds to Scenario (class)

2:46 of 6:14.. look for other Rob Conery MVC BDD tests.. others test names

CRUD

namespace Specs.CRUD {
    public class Story {

    }

    [Trait("A Valid Story is submitted", "")]
    public class ValidStoryReceived {
        [Fact(DisplayName = "A Story is added to the system")]
        public void StoryAddedToSystem() {
            throw new NotImplementedException();
        }

        [Fact(DisplayName = "A confirmation message is shown to the administrator")]
        public void ConfirmationMessage() {
            throw new NotImplementedException();
        }
    }
}

Creating classes inline with tests to begin with – Brad Wilson inspired.

Validation

public class StoryCreatorResult {
    public Story NewStory { get; set; }
    public string Message { get; set; }
    public bool Success { get; set; }
    public StoryApplication StoryApplication { get; set; }

    public StoryCreatorResult() {
        this.Success = false;
    }
}

public class StoryCreator {
    public StoryApplication ValidateApplication(StoryApplication app) {
        // do some stuff
        app.HasBeenValidated = true;
        return app;
    }

    public StoryCreatorResult CreateNewStory(StoryApplication app) {
        var result = new StoryCreatorResult();

        // validation
        result.StoryApplication = ValidateApplication(app);

        // Successful creation of story!
        result.NewStory = new Story();
        result.Message = "Successfully created a new story!";
        result.StoryApplication = app;

        return result;
    }
}


StoryCreator (Service layer)

  • takes in a StoryApplication
  • returns a StoryCreatorResult
    • NewStory (if it worked)
    • StoryApplication (with a HasBeenValidated flag)
    • Message
public enum StoryType {
    Joke,
    Video,
    Quote,
    Picture,
    AnimatedGIF
}

public class Story {
    public int ID { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int Rating { get; set; }
    public DateTime CreatedAt { get; set; }
    public StoryType StoryType { get; set; }

    public Story() {
        this.CreatedAt = DateTime.Now;
        this.StoryType = StoryType.Joke;
    }
}

Story currently has not much in it.
public class StoryApplication {
    public string Title { get; set; }
    public string Content { get; set; }
    public StoryType StoryType { get; set; }
    public bool HasBeenValidated { get; set; }

    public StoryApplication(string title, string content, StoryType storyType) {
        this.Title = title;
        this.Content = content;
        this.StoryType = storyType;
        this.HasBeenValidated = false;

        if (String.IsNullOrWhiteSpace(this.Title)
            || String.IsNullOrWhiteSpace(this.Content))
            throw new InvalidOperationException("Can't have an empty Title or Content");
    }
}

Interesting throwing on the StoryApplication if title or content are empty.  It should be handled gracefully on the client anyway so should never get to here.
[Trait("A StoryApplication is created with an empty Title or Content", "")]
public class EmptyTitle {
       
    [Fact(DisplayName = "An exception is thrown with empty title")]
    public void ApplicationInvalid() {
        Assert.Throws<InvalidOperationException>(
            () => new StoryApplication("", "content here", StoryType.Joke)
            );
    }

Testing the throw

image

2014-04-08 07.28.32
This helps a lot!

| | # 
# Thursday, 28 October 2010
( Funny )

Signing up for Azure:

image

nice :-)

F5 and it worked…

 

Windows Key and E to open explorer

image

| | #