Code Monkey home page Code Monkey logo

js-testing-battleship-engine's Introduction

Javascript Testing - Battleship Engine

Test Driven Design with MOCHA and CHAI to create a game engine (no GUI) to play the classic game, Battleship.

Tech & Dependencies

  • Javascript
  • NPM
  • Mocha
  • Chai

Install Project

  • Download from git

  • Install dependencies npm install

  • Run Tests, npm test

  • Install Mocha globally, npm install --global mocha

  • Install Mocha as a development dependency, npm install --save-dev mocha

  • test

Issues and Fixes


Notes


Notes

  • A unit test are also called "spec"
  • Install Mocha and Chai into a project: npm install --save-dev mocha chai
  • To create a basic package.json file in project and select dependencies, use: npm init
  • Mocha will test all files in the "test" folder. Naming the folder "Test", "tests", "Tests", etc. is invalid.
  • The test folder must be named "test" and be located in the same directory as package.json
  • Create a test suit containing unit tests using the describe function. describe('...', function(){...});
  • Specs/unit tests are created by, it('...', function(){...}); function.
  • The it() unit test has two arguments:
    1. a string stating what the function will test,
    2. a function with the expectations or state for the test to meet and pass
    describe(' ', function(){
    });
  • If writing test for a function is difficult, maybe the code is not needed?
  • Good unit tests improve code.Good

Mocha Reporters to Format Test Output

  mocha --reporter min
  mocha --reporter markdown
  mocha --reporter landing
  mocha --reporter nyan

More BDD Assertions

  • .not
  • .empty, checks for empty objects, arrays, or strings.
  • .deep, make deep equality comparisons. Similiar looking arrays are "deeply equal" because the deep internal value are equal.
  • .include
  • .equal
  • not.equal
  • deep.equal

Watching Test Files

  • Run test everytime the game_instance file is changed

  • mocha --watch <path to game test file> <path to function file>

    • mocha --watch ./test/game_test.js ./game_logic/game_instance.js
  • Run unit test anytime changes are made anywhere, add --watch command to package.json

    • Run the all tests in the test directory and watch for any changes in the current directory
    • Make sure to add a period ()".") at the beginning of your directory path or mocha will get confused.
    • run by typing in the terminal, npm run test:watch
    • Stop running --watch by typing, Ctrl + C
    • Watch specific files by creating a command in package.json, scripts, "test:watch:playerMethods" : "mocha --watch ./test/player_test.js ./game_logic/player_methods.js"
    "scripts": {
      "test" : "mocha",
      "test:watch" : "mocha --watch ./test ./"
    }
    
  • Add a reporter flag for minimum output, "test:watch" : "mocha --watch ./test ./ --reporter min"

Mochs and Stubs

  • [Sinon.js Mocks and Stubs](http://sinonjs.org/docs/]
  • Use fake helpers/functions needed for testing with external dependencies

Testing Asynchronouse Code with Mocha

- Mocha allows us to say that a test spec or test suite is "asynchronous" - Passing an argument to the internal function of a describe() or it() block will tell Mocha to wait on running our expectations until we specifically say so - Passing the done argument to our test spec tells Mocha that it’s supposed to wait for our instructions before checking our expectations. - Mocha will wait for done() to fire before checking the expectations

Reference


Git Notes

  • Sometimes git updates in CodeAnywhere may not work completely. A commit is registered on Github but changes are not added.
  • This git protocol works with Code Anywhere.
git add -A // To track all files
git commit -am "message" // To commit changes
git push origin master // Push your local changes to github
  • git add . will add all files, tracked and untracked.
  • git remote -v shows location/repo being pushed to -A, --all, --no-ignore-removal
    • Adds changes to all tracked files.
    • "Update the index not only where the working tree has a file matching but also where the index already has an entry. This adds, modifies, and removes index entries to match the working tree."
    • "If no is given when -A option is used, all files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories)."

-a, --all,

  • "Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected."

  • Git Docs

Sources


Unit Tests


TOC

GAME INSTANCE FUNCTIONS

checkGameStatus

should tell me when the game is over.

var players = [
  {
    ships: [
            {
              locations: [[0, 0]],
              damage: [[0, 0]]
            }
    ]
  }
];
var actual = checkGameStatus(players);
expect(actual).to.be.false;

takeTurn

should return false if the game ends.

var actual = takeTurn(player, guess);
expect(actual).to.be.false;

saveGame

should update save status.

var status = 'Game not saved...';

saveGame(function () {
  status = 'Game saved!';
  expect(status).to.equal('Game saved!');
  done();
});

Mocha

should run tests using npm.

expect(true).to.be.ok;       //ok is a Chai assertion method that checks if a value is truthy

PLAYER METHODS

validateLocation

shoud confirm valid for unoccupied locations in range.

var location = [0, 0];
var actual = validateLocation(player, location);
expect(actual).to.be.ok;

shoud confirm INvalid for occupied locations in range.

var location = [9, 9];
var actual = validateLocation(player, location);
expect(actual).to.be.false;

shoud confirm INvalid for UNoccupied locations OUT of range.

var locationHigh = [10, 10];
var locationLow = [-1, -1];
expect(validateLocation(player, locationHigh)).to.be.false;
expect(validateLocation(player, locationLow)).to.be.false;

validateLocations

should correctly report a list of unoccupied locations is valid.

var locations = [[1, 1], [1, 2], [1, 3], [1, 4]];
expect(validateLocations(player, locations)).to.be.ok;

should correctly report a a problem if any location in the list is invalid.

var locations = [[1, 1], [1, 2], [1, 3], [10, 10]];
expect(validateLocations(player, locations)).to.be.false;
locations = [[1, 1], [1, 2], [1, 3], [0, 0]];
expect(validateLocations(player, locations)).to.be.false;

placeShip

should update a ship with a valid starting location.

var ship = player.ships[0];
var coordinates = [0, 1];
placeShip(player, ship, coordinates, 'horizontal');
var actual = ship.locations;
expect(actual).to.be.ok;
expect(actual).to.have.length(1);
expect(actual[0]).to.deep.equal([0, 1]);

should throw an error if no direction is specified.

var ship = player.ships[0];
var coordinates = [0, 1];

                        var handler = function () { placeShip(player, ship, coordinates); };
                        expect(handler).to.throw(Error);
                        expect(handler).to.throw('You left out the direction! I need that for math!');

checkForShip

should correctly report no ship at a given players coordinate.

expect(checkForShip(player, [9, 9])).to.be.false;

should correctly report a ship located at a given coordinates.

expect(checkForShip(player, [0,0])).to.deep.equal(player.ships[0]);

should handle ships located at more than one coordinate.

expect(checkForShip(player, [0, 1])).to.deep.equal(player.ships[0]);
expect(checkForShip(player, [0, 0])).to.deep.equal(player.ships[0]);
expect(checkForShip(player, [9, 9])).to.be.false;

should check for multiple ships.

expect(checkForShip(player, [0,1])).to.deep.equal(player.ships[0]);
    expect(checkForShip(player, [0,0])).to.deep.equal(player.ships[0]);
    expect(checkForShip(player, [1,0])).to.deep.equal(player.ships[1]);
    expect(checkForShip(player, [1,1])).to.deep.equal(player.ships[1]);
    expect(checkForShip(player, [2,3])).to.deep.equal(player.ships[2]);
    expect(checkForShip(player, [9, 9])).to.be.false;

damageShip

should register damage on a given ship at a given location.

var ship = {
  locations: [[0, 0]],
  damage: []
};
damageShip(ship, [0, 0]);
expect(ship.damage).to.not.be.empty;
expect(ship.damage[0]).to.deep.equal([0, 0]);

fire

should report damage on a players ship at a coordinate.

fire(player, [0,0]);
expect(player.ships[0].damage[0]).to.deep.equal([0,0]);

should NOT record damage if there is no ship at coordinate.

fire(player, [9,9]);
    expect(player.ships[0].damage).to.be.empty;

js-testing-battleship-engine's People

Contributors

edwardrutz avatar

Watchers

James Cloos avatar

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.