Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option exclude certain files by pattern when testing recursively #1577

Closed
KylePDavis opened this issue Mar 4, 2015 · 73 comments
Closed

Option exclude certain files by pattern when testing recursively #1577

KylePDavis opened this issue Mar 4, 2015 · 73 comments
Labels
area: usability concerning user experience or interface good first issue new contributors should look here! status: accepting prs Mocha can use your help with this one! type: feature enhancement proposal

Comments

@KylePDavis
Copy link

I would like the ability to provide an exclusion pattern so that I can only test files that match my test file pattern. This would allow data files to coexist with test files so long as they follow a reasonable pattern.

I think this would be simply providing an option that sets ignore option in glob.

Thoughts? I can make a PR for it real quick if you'd like.

@alinex
Copy link

alinex commented Mar 5, 2015

You may better make two parallel directories, one for tests and the other
for data files. That's what I did.
Am 04.03.2015 15:52 schrieb "Kyle P Davis" notifications@github.com:

I would like the ability to provide an exclusion pattern so that I can
only test files that match my test file pattern. This would allow data
files to coexist with test files so long as they follow a reasonable
pattern.

I think this would be simply providing an option that sets ignore option
in glob.

Thoughts? I can make a PR for it real quick if you'd like.


Reply to this email directly or view it on GitHub
#1577.

@KylePDavis
Copy link
Author

I could (and have in the past) but I'd rather not have to do that anymore now that I've realized that glob ignore is right there.

It should be pretty easy to add a command line argument to set the glob ignore option. I just wanted to get thoughts and discuss a little bit first.

Any objections to me creating a PR for this?

@toddbluhm
Copy link

I was just needing this too and was surprised to see mocha did not already have it. I think it would be a great addition. We have a "testApp" inside our test folder that we use specifically for testing. We don't want mocha trying to run tests inside that folder. It would be nice to be able to just add an exclude to our mocha.opts file to exclude that specific path rather than having to explicitly include all the other test sub-folders we have.

While we could move the testApp out, it really doesn't fit anywhere else in the repo and its got relative pathing to certain files in the test folder.

This I think would be a nice addition. Certainly not critical, but helpful.

@boneskull
Copy link
Member

@KylePDavis @toddbluhm

If I needed this, I think I'd probably just

$ mocha $(find test/ ! -path '*testApp*')

So I'm not really thrilled about the idea. I'm kind of on the fence about the existence of the recursive flag even, since the same thing can be achieved with a shell command, Makefile, Gruntfile.js, gulpfile.js, etc., etc.

@danielstjules
Copy link
Contributor

danielstjules commented Mar 14, 2015

I think @boneskull makes a good point - this is already achievable in a variety of ways. And that's not including the fact that you can structure you directories to avoid this altogether. For example, given this structure:

$ tree .
.
└── spec
    ├── fixtures
    ├── integration
    └── unit

4 directories, 0 files

You just update your package.json so that you can simply run npm test

  "scripts": {
    "test": "mocha spec/unit spec/integration"
  }

Or with a structure like the following:

$ tree .
.
└── src
    └── models
        ├── user.js
        └── userSpec.js

2 directories, 2 files

You could run specs in a similar fashion as @boneskull's example (this will only run files containing Spec)

  "scripts": {
    "test": "mocha $(find src -name '*Spec.js')"
  }

Edit: Fixed :)

@boneskull
Copy link
Member

@danielstjules I think that will actually hit any dir with Spec in the name. Perhaps you want -name '*.spec.js'

@danielstjules
Copy link
Contributor

danielstjules commented Mar 15, 2015

Yup, you're right! Brainfart. Thanks for pointing that out.

Fixed command for the example:

  "scripts": {
    "test": "mocha $(find src -name '*Spec.js')"
  }

@cazzer
Copy link

cazzer commented May 21, 2015

I think there is still a valid use case for this feature: I tend to group my files by feature, so each test file is next to the files containing the logic they're testing. Naming test files consistently works with the file argument or grep option but I would like to explicitly ignore things like node_modules.

For anyone looking - gulp-mocha can achieve this, I just hate to include gulp where I don't have to.

@KrisSiegel
Copy link

I'd like to take a moment and +1 this idea. Unlike typical JavaScript projects I like to follow the way GO does unit testing and I include a spec file next to every single file that gets tested. For example a directory in one of my projects may look like the following:

main.js
main.spec.js
utilities.js
utilities.spec.js

I find this type of organization makes it far easier to find test versus digging into a single directory of test files; you always expect the test to sit right next to the file that it tests and my build script scripts all .spec.js files out in the deployed version.

Due to my non-standard layout what I'd like to be able to do is run all unit tests with all of my folders excluding the node_modules directory.

I don't have a Windows box near me at the moment but I'm not sure if that find syntax would work in Windows or not; an exclude option would be far more intuitive anyway in my opinion. Plus almost all unit test frameworks include a way of ignoring files anyway so parity would be nice.

@op1ekun
Copy link

op1ekun commented Jul 16, 2015

Hi, all my tests support *.test.js format. They are all in tests directory. Currently I have couple of tests that I want to exclude, and still retain the default path for mocha which is ./test/**/*.js. How do I do that?

Creating two separate directories will not work here, and you have to agree that moving tests between to directories would create a lot of noise in VCS.

@calebthebrewer Thankfully I'm using gulp in the project ;) thanks for the hint!

@datatypevoid
Copy link

+1 @calebthebrewer

@datatypevoid
Copy link

Angular 2.0 and Polymer have me in component mode so I agree with @KrisSiegel. Keeping all of your code in bundles keeps a clean, modular, easy-to-maintain file hierarchy.

@datatypevoid
Copy link

Is there any foreseeable problem to loading the tests using the q promise library in a fashion such as this:

import q from 'q';

import authRouterTest from '../app/routes/_authentication.router.e2e.js';

import productRouterTest from '../app/routes/_product.router.e2e.js';

import productModelTest from '../app/models/product.model.spec.js';

// Dynamically constructed sequence of functions
let funcs = [ productModelTest(), authRouterTest(), productRouterTest() ];

// This function takes an array of promise-producing functions and
// runs them sequentially.
let execTests = () => {

    let result = q();

    funcs.forEach((f) => {

        result = result.then(f);
    });

    return result;
};

// Execute tests
execTests();

This way you can import your files from wherever and just have one test file in test/.

You can resolve the promise within the last test block and wrap each test up like this

import q from 'q'

export default () => {

    let Q = q.defer();

    describe('something', () => {

        it('should', (done) => {

            ...
        });
    });

    describe('something', () => {

        it('should', (done) => {

            ...
        });

        it('should', (done) => {

            ...

            Q.resolve('test complete');
        });
    });

    return Q.promise;
};

It seems to work pretty good, unless there is something I am not considering.

@jeffbski
Copy link

We should still have an ignore for the glob. Using bash commands is not a cross platform solution.

@godspeedelbow
Copy link

+1

I really would like to exclude node_modules. Exclusion seems like a pretty handy companion to recursive.

@dead-claudia
Copy link

@godspeedelbow Why would that particular directory need explicitly ignored? I don't normally hear about node_modules being in a test directory.

FWIW, I could really use this as well. I've got a couple projects where the tests scale far more than the library itself, and this would enable me to better organize them (fixtures belong in a test directory IMHO).

@KrisSiegel
Copy link

Ignoring node_modules becomes important when you're either doing something unexpected (like me where I keep spec files next to the file it tests versus keeping them in a single folder, away from the code it tests) or if you want to run unit tests against a main project and some of its included projects (perhaps they're internal libraries, not in the npm repo, that you would like to test) but you don't want to run the unit tests within their own dependencies.

This issue has been around for almost a full year now so I don't have much hope of it being implemented. It's important, in my opinion, to implement because the workarounds either require platform specific terminal commands or you explicitly specify patterns for each directory you want to test (so additional directories need to be added to the testing script). I would fork it and just do it myself but using the hacky method of specifying each directory and a pattern is just easier than finding the time to implement it into mocha.

@dead-claudia
Copy link

@KrisSiegel You could always do src/**/*.js and src/**/*.spec.js. I see that more often in Go and Rust projects than starting in the project root. Matter of fact, the latter is relatively uncommon.

Although I think they're just waiting on someone to just take the time to do it themselves. It doesn't seem like a difficult patch to create (unless that logic is a spaghetti code state machine mess).

I'm not as driven to do this personally because I'm actually working on a test framework of my own, intended to be a complete alternative to Mocha, Jasmine, Tape, etc., although simpler and more powerful at its core. It's still too much a work in progress for even toy projects ATM, though.

@dead-claudia
Copy link

I'm using Mocha to effectively bootstrap the framework. I used Chai initially for the assertions until I got those stabilized (they're practically API locked now, since I'm using the framework's assertions to test itself).

@KrisSiegel
Copy link

Yeah that's a workaround I just don't see many JavaScript projects structured that way though the same could be said about pairing the spec and source file as well. I essentially use that pattern though when I come into projects that are already pretty large with their own custom build systems it's not always easy to change it up.

Exclude is a pretty basic pattern a lot of utilities have. I think mocha needs it :). Though I guess my impression, since this issue was closed based around platform specific workarounds, that it was not desired versus awaiting a patch. If this is something the mocha folks would actually want then if it's not done in a few weeks I could certainly crank out a patch.

@dead-claudia
Copy link

@KrisSiegel I'm pretty sure that if someone actually cranked out a patch, it would probably get merged, as long as it doesn't involve some unintuitive, special syntax or extra flag. FWIW, there's yet to be a PR for this, and the reason this issue was closed was pretty weak if you consider the platform-dependent. And I don't see very many Windows users that are willing to install GNU find just to run a few tests.

It may be closed, but a similar situation is already happening to Node with Web workers, although Node's implementation will slightly deviate (closed issue, PR in progress).

@adamreisnz
Copy link

+1 for what it's worth. A project I've built doesn't require an app or src folder, but instead has a variable amount of named folders with different interface implementations. I would also like to keep my tests bundled for each interface, and not be forced to use a single folder for tests.

Being able to specify files to ignore with a .mochaignore or other option would be ideal, as that way I could just run it with a **/*.spec.js glob and not worry that it might include tests from the node_modules folder.

Almost all other build tools allow this, we have .npmignore, .gitignore, .jshintignore, and jscs provides an option to configure it via .jscsrc. It would be useful if Mocha would support it as well, as more and more people are moving towards the component/feature file and folder organisation, away from the sock drawer approach.

@godspeedelbow
Copy link

@isiahmeadows like others mentioned, I'm stuck with a folder structure I can't easily change, therefore services/, routes/, etc. are in the root of the project just like node_modules is. I got inspired to put test files next to the files they test. This works really great, but I need a third tool (be it command line, or gulp, or something else) to exclude node_modules so that only my own tests get tested.

I'd love to implement it myself in mocha, if I'd knew where to start :)

@danielstjules
Copy link
Contributor

@godspeedelbow @adambuczynski A temporary solution :)

  "scripts": {
    "test": "mocha $(find . -name '*.spec.js' ! -ipath '*node_modules*')"
  }

@godspeedelbow
Copy link

Hi @danielstjules thanks! Tried it, but for some reason find . -name '*.spec.js' ! -ipath '*node_modules*' only finds one test file.

@danielstjules
Copy link
Contributor

Did you update '*.spec.js' to fit the pattern your tests follow? E.g. to match all js files, you'd use:

  "scripts": {
    "test": "mocha $(find . -name '*.js' ! -ipath '*node_modules*')"
  }

@adamreisnz
Copy link

@danielstjules cheers, but that wouldn't work on windows I believe, and while for this app it's not a problem, I am hesitant to put it in.

In the mean time, I've resorted to moving the app code and tests to an app subfolder so that I can target that folder for the tests and not worry about node_modules or other folders.

@godspeedelbow
Copy link

@danielstjules yeah, all test files are in format of *.spec.js. For some reason it didn't work earlier, but now when it does without problems. Thanks for this *NIX work around.

@boneskull
Copy link
Member

In addition, .mochaignore (#2036) support sounds good, but is a separate issue. There should be a 3p module we can pull in to have .gitignore-like behavior; I'm sure whatever ESLint is doing is good enough for our purposes.

@boneskull
Copy link
Member

...and if it isn't clear, don't use unquoted globs on the command line; see #2355

@tiendq
Copy link

tiendq commented Nov 24, 2016

Surprisingly there's still no option like --ignore-path, besides putting all tests into a tests folder, there's no reason why we can't put tests along with modules.

@masmau
Copy link

masmau commented Dec 16, 2016

+1
ignore files or directories by pattern is a very useful feature

@catamphetamine
Copy link

catamphetamine commented Dec 16, 2016

@isiahmeadows

You could always do src//*.js and src//*.spec.js

No, you couldn't - the **/* pattern matching is broken and doesn't work recursively.

EDIT: @ScottFreeCode has the answer below

@ScottFreeCode
Copy link
Contributor

the **/* pattern matching is broken and doesn't work recursively.

Are your paths quoted?

@nickcodefresh
Copy link

+1

@matteocontrini
Copy link

image

@ghost
Copy link

ghost commented Mar 20, 2017

As describe in zinserjan/mocha-webpack#124:

Inside src/ there is a file called server.ts which fires an express server, and runs at the background. The server is typically up when running coverage, so the port is already in use.

So we don't want this and only this file to be excluded.

@codebykumbi
Copy link

http://remarkablemark.org/blog/2017/02/07/mocha-glob-pattern/

@alexanderankin
Copy link

Voicing my opinion that mocha needs an ignore because even after all this time, maintainers still need convincing.

Mocha is canon. why not raise the bar for the cross-platform feature set of the test framework that all other test frameworks aspire to be? We should stop aspiring to leaving everything up to Bash. Its 2017 already.

@dead-claudia
Copy link

I'll also point out that Windows people don't have anything equivalent to Bash's !(glob) (which is actually a Bash-ism, not even POSIX standard).

@ScottFreeCode
Copy link
Contributor

There shouldn't be any Bash dependency in Mocha's globbing as-is, since it is processed through the Glob JS module. (Note: quoting the paths may be required to avoid the shell processing globs differently from how Mocha would, e.g. ** without the globstar extension or whatever it is that makes that special.)

@dead-claudia
Copy link

@ScottFreeCode Do you use extglob: true when you use glob? If that's the case, then this can be closed with that syntax as a workaround (since glob/minimatch supports it with that option enabled).

@ScottFreeCode
Copy link
Contributor

It looks like we're just passing the path to glob. I am pretty sure that I got negation working through a glob pattern at some point, but that may have been an older version of the module? In any case, we do have tests for the double-star behavior, so if anyone wants to submit tests to confirm that some negation patterns work too (or if anyone finds any flaws in the globbing tests we already have), that would be great.

However, there's a definite advantage to having an explicit ignore/exclude option. Multiple advantages, actually:

  • less obscure
  • easier to avoid clashes with different OSes special characters and quoting rules
  • an include list minus an exclude list is simpler in many cases than an include list with negated pieces

I merely wanted to clarify that the status quo isn't meant to be relying on any particular shell. ;^)

@dead-claudia
Copy link

an include list minus an exclude list is simpler in many cases than an include list with negated pieces

True, and I had almost forgotten about that 😄

@boneskull
Copy link
Member

Anyone coming to this issue:

The workaround is now to use globs, as this should be supported. If someone wants this particular behavior, please send a PR.

@boneskull boneskull added the good first issue new contributors should look here! label Oct 18, 2017
@boneskull boneskull added the area: usability concerning user experience or interface label Jan 19, 2018
boneskull pushed a commit that referenced this issue Apr 1, 2018
* Add --exclude as option.

* Add tests for --exclude option.

* Implement --exclude.

* Update --exclude description.

* Remove old exclude fixture.

* Add new exclude fixture.

* Fix tests for --exclude option.

* Add name to package.contributors.

* Filter new files before they're added.

* Allow multiple --exclude flags rather than using a comma-delimited list.

* Use .fixture extension for exclude fixtures.

* Use runMochaJSON (run) instead of of directInvoke.
@sepo-one
Copy link

Does --exclude option work ?
Can't find it in docs.

@outsideris
Copy link
Member

outsideris commented Jul 12, 2018

@sepo-one I opened PR to update the document.
You can see all available options vis mocha -h.

@sepo-one
Copy link

Yea, i've been using old version of mocha. Upgraded and --exclude option is there.
Docs should be updated anyway i guess.

Thanks @outsideris

sgilroy pushed a commit to TwineHealth/mocha that referenced this issue Feb 27, 2019
* Add --exclude as option.

* Add tests for --exclude option.

* Implement --exclude.

* Update --exclude description.

* Remove old exclude fixture.

* Add new exclude fixture.

* Fix tests for --exclude option.

* Add name to package.contributors.

* Filter new files before they're added.

* Allow multiple --exclude flags rather than using a comma-delimited list.

* Use .fixture extension for exclude fixtures.

* Use runMochaJSON (run) instead of of directInvoke.
@jtakalai
Copy link

This ought to be available in MochaOptions type as well, then. There is no exclude or ignore in https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/mocha/index.d.ts#L2258

Is this a types issue (that "ignore" option exists as it's found in https://github.com/mochajs/mocha/blob/master/example/config/.mocharc.js but not added to type) or does the "non-cli library" not support ignore? I'll submit PR to DefinitelyTyped if you can assure it should work.

@ahmedelbougha
Copy link

ahmedelbougha commented Mar 7, 2022

Just for people who may come later to read this, Mocha supports --ignore, --exclude to ignore files or glob patterns.
Examples:

--ignore '**/mytest.js'
--ignore '**/m*.js'
--ignore '**/mytest.*'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: usability concerning user experience or interface good first issue new contributors should look here! status: accepting prs Mocha can use your help with this one! type: feature enhancement proposal
Projects
None yet
Development

No branches or pull requests