Git Product home page Git Product logo

vow's Introduction

Adonis vow πŸ’‚

| Test runner for Adonis framework with batteries included πŸ”‹

NPM Version Build Status Appveyor Coveralls

Adonis vow is the test runner for Adonis framework, just install and register the provider and BOOM it just works.

Setup

adonis install @adonisjs/vow

Read setup instructions

Concepts

The test runner is bare bones that you need to setup and run tests using your command line. But it comes with a powerful concept of traits.

Traits

Traits are building blocks for your tests. Features like Database transactions, Api client, Browser client, they all are built on top of the API provided by traits.

const { trait } = use('Test/Suite')('Sample test suite')

trait((suiteInstance) => {
})

Suite

A test suite is a combination of tests that you want to group inside a single file or group them logically.

Each suite has it's own set of traits, which means adding traits for a single suite, doesn't collides with the other suite :)

Hooks

Each suite has a lifecycle and you can hook into that lifecycle by adding methods to one of the following events.

const suite = use('Test/Suite')('Sample test suite') 

suite.before(() => {
 // executed before the suite
})

suite.after(() => {
 // executed after the suite
})

suite.beforeEach(() => {
 // executed before each test
})

suite.afterEach(() => {
 // executed after each test
})

Context

Each test suite has a context, which is instantiated and passed to each test, so this is the right place to hook stuff that you want to be available to tests.

const { trait, test } = use('Test/Suite')('Sample test suite')

trait((suite) => {
  suite.Context.getter('foo', () => 'bar')
})


test('foo is bar', (ctx) => {
  ctx.assert(ctx.foo, 'bar')
})

// using es6 destructuring
test('foo is bar', ({ foo, assert }) => {
  assert(foo, 'bar')
})

Development

The tests for the test runner are written using japa and make sure to go through the docs.

Release History

Checkout CHANGELOG.md file for release history.

Meta

AdonisJs – @adonisframework – [email protected]

Checkout LICENSE.txt for license information

Harminder Virk (Aman) - https://github.com/thetutlage

vow's People

Contributors

diego3g avatar dv336699 avatar erikkallen avatar radmen avatar richie3366 avatar romainlanz avatar thetutlage 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

Watchers

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

vow's Issues

Adding custom reporter

Why this feature is required (specific use-cases will be appreciated)?

I would like to generate a pdf report based on the test results, other test tools have multiple reporters and I would like to be able to add my own.

Have you tried any other work arounds?

I have cloned and edited both the JAPA and adonis-vow repository and tried to copy and edit the list reporter that is currently the only option and I tried to activate it using the REPORTER env variable but I cannot get it to output any report (not even the default list report)

Are you willing to work on it with little guidance?

I am willing to work on this

Can we nest testing scenarios?

Look at example:
Mocha
In Mocha it is

describe('module name', () => {
  describe('when condition', () => {
    it('should de what is expected', () => {
      assert(1,1)
    })
  })
} )

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

Error: Cannot find module 'Session/Client'

I have a simple code to test REST Api use Authentication and my code is simple like

const { test, trait } = use('Test/Suite')('Role')
const UserModel = use('App/Models/User')

trait('Test/ApiClient')
trait('Session/Client')
trait('Auth/Client')

test('test role get all', async ({ client }) => {
  console.log('ok')
})

it throws error Error: Cannot find module 'Session/Client'.

how to install the module?

Post Request Test with Database Transaction Trait fails

If I use the database transaction trait with a post request, an error ending with:

the current transaction is aborted, command ignored till the end of the transaction block

example code:

...

trait('Test/ApiClient')
trait('DatabaseTransactions')

test('can register a new user', async ({ client }) => {
  const newUser = {....}

  const response = await client
    .post('/register')
    .send(newUser)
    .end()

  response.assertStatus(200) // fails here with a 500 status
  response.assertJSONSubset([newUser])
})

Note: I've tested that similar logic works if I create a user via Lucid Model methods

error: `make:test` is not a registered command

Follow this guide (
http://adonisjs.com/docs/4.0/browser-tests), but error when run ace command make:test :

error: 'make:test' is not a registered command

"dependencies": {
    "@adonisjs/ace": "^4.0.7",
    "@adonisjs/auth": "^2.0.10",
    "@adonisjs/bodyparser": "^2.0.0",
    "@adonisjs/cors": "^1.0.3",
    "@adonisjs/fold": "^4.0.5",
    "@adonisjs/framework": "^4.0.28",
    "@adonisjs/ignitor": "^1.0.14",
    "@adonisjs/lucid": "^4.0.24",
    "@adonisjs/session": "^1.0.19",
    "@adonisjs/shield": "^1.0.4",
    "@adonisjs/vow-browser": "^1.0.5"
  },

Can't test against data that already exists using trait('DatabaseTransaction')

I'm like 3 hours new to Adonis and I'm having trouble testing a simple list view that should return JSON.
Since the data already exists in my database, I get:

error: duplicate key value violates unique constraint "cities_pkey"
    at Connection.parseE (/home/rombus/Workspace/codetemp/js/tdr2/node_modules/pg/lib/connection.js:545:11)
    at Connection.parseMessage (/home/rombus/Workspace/codetemp/js/tdr2/node_modules/pg/lib/connection.js:370:19)
    at Socket.<anonymous> (/home/rombus/Workspace/codetemp/js/tdr2/node_modules/pg/lib/connection.js:113:22)
    at Socket.emit (events.js:159:13)
    at addChunk (_stream_readable.js:265:12)
    at readableAddChunk (_stream_readable.js:252:11)
    at Socket.Readable.push (_stream_readable.js:209:10)
    at TCP.onread (net.js:608:20)

Is there anyway to run tests in a different database? Something like in django or rails when you have a adonis_test database?

Here is my test code just incase I'm missing something important!

'use strict'

const { test, trait } = use('Test/Suite')('City')
const City = use('App/Models/City')

trait('DatabaseTransactions')
trait('Test/ApiClient')

test('get list of cities', async ({ client }) => {
  await City.create({
    code: 'NYC',
    name: 'New York City'
  })

  const response = await client.get('/api/v1/cities').end()

  response.assertStatus(200)
  response.assertJSONSubset([{
    code: 'NYC',
    name: 'New York City'
  }])
})

Do I need to use mocks for these? I think that's what I'm missing but there's not much information on it that I can find from cursory google searches.

adonis make:test fails and hangs

Package version

"@adonisjs/vow": "^1.0.17",

Node.js and npm version

Node: v10.15.3
npm: 6.4.1

Sample Code (to reproduce the issue)

adonis make:test simpleTest

Expected Output

Test File is generated
Console does not hang?

Adonis session not persisting between tests

I've built a simple eCommerce application on Adonis JS. I'm trying to test the cart functionality where if the user adds an item to the cart and if it's already there in the cart, then it should simply increase the quantity. For this, I'm hitting the cart API twice to check the functionality. However, my session isn't persisted between requests because of which each time I receive only one quantity.

Package version

"@adonisjs/framework": "^5.0.9",
"@adonisjs/vow": "^1.0.17",

Node.js and npm version

Node - v14.15.4
NPM - 6.14.10

Sample Code (to reproduce the issue)

test('should increase the quantity if user tries to add the same item to cart', async ({ assert, client }) => {
    const menu = await createMenu(client);
    // Simply adds to cart
    await client.post(`/cart/${menu.id}`).send({
        quantity: 1,
    }).end();

    // It should increase the quantity to 2 now.
    const response = await client.post(`/cart/${menu.id}`).send({
        quantity: 1,
    }).end();

    response.assertStatus(200);
    // There should be only one item in cart
    assert.equal(response.body.data.items.length, 1);
    // And quantity of that item should be 2.
    assert.equal(response.body.data.items[0].quantity, 2);
});

Asynchronous trait

I want to know how I could make a trait getter asynchronous.

trait((suite) => {
  suite.Context.getter('foo', async () => getAsyncFoo());
});

doesn't seem to work. What I currently do instead is execute the getAsyncFoo() inside the beforeEach hook, push the result to an array and pop it in the getter of the trait. Calling getAsyncFoo directly would make this a lot easier. Is there any way to achieve this?

I also thought about 'foo' just returning an unresolved promise and then awaiting it inside the tests but this would sort of defeat the purpose of simply injecting values via traits into each test. By returning a promise that has yet to be completed inside the getter I would have to await the promise in each test.

Tests does not call authorize inside validators

Hi!

I use the authorize method inside a model and it runs fine. But when i run my tests, the method will not be called. If icall my route via a rest client i can see the console.log('authorize') , when run test the method will not called.

class StoreRemoteSystem {
  /**
   * Define the Validation-Rule (Object)
   */
  get rules() {
    return {
      name: 'required|string|max:80',
      description: 'string|max:254',
      protocol: 'required|string|max:20',
      host: 'string|string|max:254',
      port: 'required|integer',
      username: 'required|max:254',
      password: 'required|max:254',
      domain: 'alphaNumeric|max:254',
      database: 'max:254'
    };
  }

  async authorize() {
    console.log('authorize');

    const canStore = this.ctx.auth.user.can_update_credentials;

    if (!canStore) {
      this.ctx.response.unauthorized('Not authorized');
      return false;
    }

    return true;
  }

the test:

test('Get a list of all stored users', async ({ assert, client }) => {
  const response = await client
    .get('/users')
    .loginVia(user.email, 'Start12#', 'basic')
    .end();

  response.assertStatus(200);
}).timeout(30000);

Bug, or did i miss something?

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

assertStatus(200) returns 500 instead, if using auth.user.id in the query in controller

Code:

Controller:

async index({ auth }) {

// get an user object of a currently logged in user
  const user = await User.query().where('id', auth.user.id).firstOrFail()

// post is a method in User model
  const posts = await user.posts().fetch()

  return posts
}

Model:

posts() {
    return this.hasMany('App/Models/Post')
  }

functional test

'use strict'

const { test, trait } = use('Test/Suite')('Users')
const User = use('App/Models/User')

trait('Test/ApiClient')
trait('Session/Client')
trait('Auth/Client')

test('get list of logged in user posts', async ({ client }) => {
  const user = await User.find(1)

  const response = await client
  .get('posts')
  .loginVia(user)
  .end()

response.assertStatus(200) //500 instead of 200
console.log(response) //text: 'TypeError: Cannot read property \'id\' of null',

If I change auth.user.id to 1 in Controller for example, it passes.

Response Assert Json Structure

It would be great if there was a function on the like in Laravel that allows you to verify the structure of the JSON response rather than specific value as in all case you might not be interested what really in the data want to be sure that it is present.

e.g. response.assertJSONStructure([ 'bearer', 'token', 'refreshToken ]);

Why this feature is required (specific use-cases will be appreciated)?

It's very much a nice to have. However in my case I am testing a sort of register user endpoint and expect back the auth object. I would like to verify that the token is part of the response but I generally don't care what the actual value is.

Have you tried any other work arounds?

This seems to do the job however it's not particularly clear to read.
assert.containsAllKeys(response.body, ['token'])

Are you willing to work on it with little guidance?

yes

.only option

Would be useful to have test.only method, or a exported function to specify to run only one test and ignore the rest in the file.

The use case is for debugging. When running a debugger on a test file, usually you want to skip all but one tests. Now I have to comment them all out, except one.

Also not possible to use --grep in an integrated environment, such as VS Code launch mode.

When writing tests, how can I get data in session ?

From @nioperas06 on June 26, 2018 11:44

Let's assume that in a controller I set data in my session. How can I get this data in my tests?

const { test, trait } = use('Test/Suite')('Post')

trait('Test/ApiClient')
trait('Session/Client')

test('get list of posts and session data ', async ({ client }) => {
  const response = await client
    .get('posts')
    .end()
// Test session data here
})
Thanks.

Copied from original issue: adonisjs/core#900

Ability to set hook timeouts

Why this feature is required (specific use-cases will be appreciated)?

Currently, trying to populate complex data on the before() hook may result in it timing out, leaving the data inconsistent and crashing the other tests.

Have you tried any other work arounds?

It's possible to populating the suite data on a test, but it kind of defuses the purpose of having these hooks.

Are you willing to work on it with little guidance?

Yes.

list of directories to run tests from in config file

Prerequisites

nothing

Why this feature is required (specific use-cases will be appreciated)?

I want to make modules system so i need multiple testing directories

Have you tried any other work arounds?

nested directories inside the main tests directory but it is not enough

Are you willing to work on it with little guidance?

I am willing . but I do not know the internal code of the framework

list of directories to run tests from in config file

Prerequisites

Probably not a bug but a question.

My issue is completely the same as this one from 2018. Yet the solution proposed there does not work for me.

Package version

Adonis 4.1.0

Node.js and npm version

Node: 12.6
Npm: 6.14

Issue Description

Hello colleagues, I need to engage tests from test/integration/ folder. I add the advised in the former issue solution cli.group('e2e', 'test/integration/**/*.spec.js') into vowfile.js as follows:

module.exports = (cli, runner) => {
  runner.before(async () => {
    cli.group('integration', 'test/integration/**/*.spec.js');
//... remaining code here

with no effect. The tests only run from ``test/unit/` folder.

How can I run tests from folders test/**/ other than test/unit/?

PS: Just to confirm the tests are not run if I put them under folders other than test/unit/ i.e. test/ or test/integration/. Only thos in test/unit/ are run.

--watch option

Is there any way to watch for spec changes and re-run the tests automatically instead of running the command every time manually?

Using DatabaseTransactions does not play well with app transactions

Test:

trait('DatabaseTransactions')

test('...', async ({ assert }) => {
  // this is created inside a trx1 via DatabaseTransactions
  const user = await Factory
    .model('App/Models/User')
    .create()

  const res = await userFacade.doStuff(user, 'foo')
})

App code (App/Facades/userFacade.js):

  async doStuff (user, foo) {
    // will start a new trx2, which then does not see the user previously created outside of this txn
    const trx = await use('Database').beginTransaction()

    await user.stuff().create({}, trx)
  }

Test methods not chainable

Package version

4.1.0

Node.js and npm version

Node - 11.14.0
NPM - 6.9.0

Sample Code (to reproduce the issue)

These work:-

test('test name', async (ctx) => {
  // This works
}).timeout(100)
test('test name', async (ctx) => {
  // This works
}).retry(3)

However, these do not:-

test('test name', async (ctx) => {
 // This doesn't work
}).timeout(100).retry(3)
test('test name', async (ctx) => {
 // This doesn't work
}).retry(3).timeout(100)

It produces this error:-

TypeError: Cannot read property 'retry' of undefined

Test/ApiClient send is not processing data the same way server does

Using PHP-style post params:

  'transaction[0][event]': 'sales',
  'transaction[0][mode]': 'test',
  'transaction[0][payment_processor]': 'testmode',

The server parses this correctly into an object transparently, which was a pleasant surprise.

However, when submitting the same via Test/ApiClient's send method, the values end up being flat.

Test file upload

Hi,

I'm wondering if it is possible to simulate a file upload. For example, in my ReactJS, I use FormData to send a file to Adonis, which uses request.file(). An example of an output of a file would be the following:

[File(234234)]
  0: File(234234)
    lastModified: "...",
    lastModifiedDate: "...",
    name: "filename.png",
    preview: "..."
   ...
...

Then, in my test file, I attempted to send a JSON in this format, but it's no good.

const request = await client.post("http://127.0.0.1:4000/api/v1/invoices/1/additional-files")
  .send({
    id: 4,
    invoice_id: 1,
    File: {
      name: "a_new_file_uploaded.png"
    },
    description: "Lorem ipsum dolor sit amet"
  })
  .end();

Is there another way to simulate a file?

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.