Git Product home page Git Product logo

express-app-testing-demo's Introduction

express-app-testing-demo

This project is a simple express app for demonstrating testing and code coverage. Jest and Supertest are used for testing. Jest is also used for mocking functions and measuring code coverage. Note that this app only focuses on server-side JavaScript testing.

Requirements

Getting Started

  • Clone the repo
  • Install dependencies with npm install
  • Run server with npm start and go here: http://localhost:3000/

Running Tests

  • Run unit and integration tests: npm test
  • Run end-to-end tests: npm run test:e2e

Code Coverage Report

A new code coverage report is generated every time npm test runs. Normally this coverage report is ignored by git. This project includes it in source control so the coverage report can be viewed in the demo app: http://express-app-testing-demo.herokuapp.com/coverage/lcov-report/index.html

express-app-testing-demo's People

Contributors

gregjopa avatar mortonfox 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

express-app-testing-demo's Issues

promise returning ??

Hi there,

I am facing difficulties in this particular piece of code:
File route.js

// get photos from flickr public feed api
    return photoModel
      .getFlickrPhotos(tags, tagmode)
      .then(photos => {
        ejsLocalVariables.photos = photos;
        ejsLocalVariables.searchResults = true;
        return res.render('index', ejsLocalVariables);
      })
      .catch(error => {
        return res.status(500).send({ error });
      });

whereas,
in file photo_model.js, the function getFlickrPhotos is not returning any promise. Can you please help me understand how is that intended to work.
The .then() function above is getting its 'photos' from the previously resolved promise, ryt ? but noone seems to be doing that.

Use of requirehelper

In our project we store all test file under test folder near each module instead of /root/test. Also we are using mongoose client for mongodb. So all mongoose models are loaded in server.js/index.js where server is started, so it doesn't make sense to user require_helper in production code.

So we needed a way to tell require to use instrumented file instead on source file without using requireHelper, So we used require.extension. Here is sample code for our requireHelper.js

if (process.env.APP_DIR_FOR_CODE_COVERAGE) {
    var extname = '.js',
        ext_super = require.extensions[extname],
        filePatternMatch = /\/app\/(?!.*\/test\/)(?!.*_spec\.).*\.(js$)/;
    require.extensions[extname] = function ext(module, filename) {
        filename = filename.match(filePatternMatch) ? filename.replace('/app/', process.env.APP_DIR_FOR_CODE_COVERAGE) : filename;
        return ext_super(module, filename);
    };
}

How jest coverage did count res.render() as tested?

First, sorry to create an issue to ask a question. Its already some time trying to solve this but I don't find an explanation.

I see in your tests this one where you test your root route.
Jest coverage is counting res.render() as tested at this point which seems perfectly fine to me.

In my case I have this test

describe('index route', () => {
  test('should return 200 OK', async () => {
    return request(app)
      .get('/')
      .expect('Content-Type', /html/)
      .expect(200)
      .then((response) => {
        expect(response.text).toMatch(
          /<title>Express<\/title>/
        )
      })
  })
})

For this route

var express = require('express')
var router = express.Router()

/* GET home page. */
router.get('/', (req, res, next) => {
  return res.render('index', { title: 'Express' })
})

module.exports = router

And jest --coverage directly points at this line as Uncovered line:

return res.render('index', { title: 'Express' })

Did you face this problem while creating your example?

Thank you very much,

Fatal error: No coverage information was collected

Running grunt test works file, grunt coverage is giving me the above error.

My Gruntfile:

module.exports = function (grunt) {

  // configuration
  grunt.initConfig({


    jshint: {
      options: {
        jshintrc: '.jshintrc',
        ignores: ['test/coverage/**/*.js']
      },
      files: {
        src: ['index.js', 'server/**/*.js', 'test/**/*.js']
      },
      gruntfile: {
        src: 'Gruntfile.js'
      }
    },


    watch: {
      lint: {
        files: '<%= jshint.files.src %>',
        tasks: 'jshint'
      },
      test: {
        files: ['test/unit/*.js'],
        tasks: ['jshint', 'mochaTest:unit']
      }
    },


    nodemon: {
      dev: {
        script: 'index.js',
        options: {
          ext: 'js,json'
        }
      }
    },


    concurrent: {
      target: {
        tasks: ['nodemon', 'watch'],
        options: {
          logConcurrentOutput: true
        }
      }
    },


    mochaTest: {
      unit: {
        options: {
          reporter: 'spec'
        },
        src: ['test/unit/*.js']
      },
      api: {
        options: {
          reporter: 'spec'
        },
        src: ['test/api/*.js']
      }
    },


    // start - code coverage settings

    env: {
      coverage: {
        APP_DIR_FOR_CODE_COVERAGE: 'test/coverage/instrument/'
      }
    },


    clean: {
      coverage: {
        src: ['test/coverage/']
      }
    },


    copy: {
      views: {
        expand: true,
        flatten: true,
        src: ['server/views/*'],
        dest: 'test/coverage/instrument/server/views'
      }
    },


    instrument: {
      files: ['index.js', 'server/**/*.js'],
      options: {
        lazy: true,
        basePath: 'test/coverage/instrument/'
      }
    },


    storeCoverage: {
      options: {
        dir: 'test/coverage/reports'
      }
    },


    makeReport: {
      src: 'test/coverage/reports/**/*.json',
      options: {
        type: 'lcov',
        dir: 'test/coverage/reports',
        print: 'detail'
      }
    }

    // end - code coverage settings

  });


  // plugins
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-nodemon');
  grunt.loadNpmTasks('grunt-concurrent');
  grunt.loadNpmTasks('grunt-istanbul');
  grunt.loadNpmTasks('grunt-env');


  // tasks
  grunt.registerTask('server', ['concurrent:target']);
  grunt.registerTask('default', ['jshint', 'server']);
  grunt.registerTask('test', ['mochaTest:unit', 'mochaTest:api']);

  grunt.registerTask('coverage', ['jshint', 'clean', 'copy:views', 'env:coverage',
    'instrument', 'mochaTest:unit', 'mochaTest:api', 'storeCoverage', 'makeReport']);

};

Output from running grunt coverage:

Running "jshint:files" (jshint) task
>> 24 files lint free.

Running "jshint:gruntfile" (jshint) task
>> 1 file lint free.

Running "clean:coverage" (clean) task
>> 1 path cleaned.

Running "copy:views" (copy) task


Running "env:coverage" (env) task

Running "instrument" task
Instrumented 22 files (skipped 0 files)

Running "mochaTest:unit" (mochaTest) task


  exampleDescription
    #exampleFunction()
      ✓ description


  1 passing (23ms)


Running "mochaTest:api" (mochaTest) task


POST /exampleRoute 200 43.019 ms - 1583
  ✓ description (71ms)

  1 passing (73ms)


Running "storeCoverage" task
Fatal error: No coverage information was collected

I cannot see where the storeCoverage is failing. Any advice?

My folder structure is:
index.js (the entrypoint)
Gruntfile.js
package.json
server/
- api/
- auth/
- (more folders)
test/
- api/
- unit/
- coverage/ (added after running grunt coverage)

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.