diff --git a/docs-next/astro.config.ts b/docs-next/astro.config.ts index eb4f2bb994..34aa6ddc08 100644 --- a/docs-next/astro.config.ts +++ b/docs-next/astro.config.ts @@ -116,6 +116,10 @@ export default defineConfig({ label: "Find global leaks", slug: "explainers/find-global-leaks", }, + { + label: "Mess with globals", + slug: "explainers/mess-with-globals", + }, { label: "Node.js native ESM support", slug: "explainers/nodejs-native-esm-support", @@ -136,11 +140,16 @@ export default defineConfig({ label: "Spies", slug: "explainers/spies", }, + { + label: "Stub stdout", + slug: "explainers/stub-stdout", + }, { label: "Tagging with --grep", slug: "explainers/tagging", }, - { label: "Test duration", slug: "explainers/test-duration" }, + { label: "Test duration", + slug: "explainers/test-duration" }, { label: "Test fixture decision tree", slug: "explainers/test-fixture-decision-tree", @@ -153,6 +162,10 @@ export default defineConfig({ label: "Third party UIs", slug: "explainers/third-party-uis", }, + { + label: "Use environment variables", + slug: "explainers/environment-variables", + }, ], label: "Explainers", }, diff --git a/docs-next/src/content/docs/explainers/environment-variables.mdx b/docs-next/src/content/docs/explainers/environment-variables.mdx new file mode 100644 index 0000000000..0476966ecd --- /dev/null +++ b/docs-next/src/content/docs/explainers/environment-variables.mdx @@ -0,0 +1,35 @@ +--- +description: Learn how to use environment variables in Mocha tests +title: "Environment variables" +--- + +Sometimes you might want your test to make use of variables set on an environment-level. Common reasons for this include: + +- Flagging a run as CI +- Setting the domain of an application +- Pointing to a test database +- Setting a key which you want to remain secure + +The best way to do this is to use NodeJS's native environmental variables. + +## Example + +In your `package.json` or directly in a terminal set your variable name and value. + +```bash +env CI=STAGE mocha +``` + +Then in your test or code reference it via `process.env.CI`. e.g. + +```javascript +if (process.env.CI === "STAGE") // do something +``` + +The value is available from anywhere in a spec file allowing you to set values from it before the tests run. e.g. + +```javascript +const URL = `${process.env.APP_HOST}/${process.env.APP_URI}`; +describe('Test the page loads',() { +// tests ... +``` diff --git a/docs-next/src/content/docs/explainers/mess-with-globals.mdx b/docs-next/src/content/docs/explainers/mess-with-globals.mdx new file mode 100644 index 0000000000..e8bfeea138 --- /dev/null +++ b/docs-next/src/content/docs/explainers/mess-with-globals.mdx @@ -0,0 +1,60 @@ +--- +description: How to work with global variables in Mocha tests +title: "Globals" +--- + +Related issue [#1582](https://github.com/mochajs/mocha/issues/1582) + +If your test manipulates globals, a reasonable expectation is that you will clean up after yourself. This includes commonly called methods such as `process.stdout.write()` or `console.log()`. + +```js +var expect = require("chai").expect; + +describe("my nice test", function () { + var write, + log, + output = ""; + + // restore process.stdout.write() and console.log() to their previous glory + var cleanup = function () { + process.stdout.write = write; + console.log = log; + output = ""; + }; + + beforeEach(function () { + // store these functions to restore later because we are messing with them + write = process.stdout.write; + log = console.log; + + // our stub will concatenate any output to a string + process.stdout.write = console.log = function (s) { + output += s; + }; + }); + + // restore after each test + afterEach(cleanup); + + it("should suppress all output if a non-AssertionError was thrown", function () { + process.stdout.write("foo"); + console.log("bar"); + // uncomment below line to suppress output, which is bad + // expect(output).to.equal(foobar); + expect(output).to.equal("foobar"); + }); + + it("should not suppress any output", function () { + try { + process.stdout.write("foo"); + console.log("bar"); + // uncomment below line to just throw an AssertionError + // expect(output).to.equal('barfoo'); + expect(output).to.equal(foobar); // ReferenceError + } catch (e) { + cleanup(); + throw e; + } + }); +}); +``` diff --git a/docs-next/src/content/docs/explainers/stub-stdout.mdx b/docs-next/src/content/docs/explainers/stub-stdout.mdx new file mode 100644 index 0000000000..2952ccfa2b --- /dev/null +++ b/docs-next/src/content/docs/explainers/stub-stdout.mdx @@ -0,0 +1,34 @@ +--- +description: Learn how to properly stub stdout for testing console output +title: "Stubbing stdout" +--- + +If you want to stub stdout inside your own code (via `process.stdout.write` or `console.log`) there is a potential to hinder Mochas reporters output. This is because they rely on the same mechanisms to print results of the tests. + +i.e. + +```javascript +it('should do, but it do not', function() { + // user wants to hide output generated by console.log calls in fn 'foo' + console.log = function() {}; + foo(); + + expect(...) +}); +``` + +This will result in a faulty reporter output. + +The correct way to handle this is to stub before and restore after the function call. + +```javascript +it('will do', function() { + var consoleLogStub = sinon.stub(console, 'log'); + foo(); + consoleLogStub.restore(); + + expect(...) +}); +``` + +Now the reporters can run and print the assertion without any interference, while stubbing stdout inside your function. diff --git a/docs/api-tutorials/environment-variables.md b/docs/api-tutorials/environment-variables.md new file mode 100644 index 0000000000..baa2164afc --- /dev/null +++ b/docs/api-tutorials/environment-variables.md @@ -0,0 +1,36 @@ +# Environment variables + +Sometimes you might want your test to make use of variables set on an environment-level. Common reasons for this include + +- Flagging a run as CI +- Setting the domain of an application +- Pointing to a test database +- Setting a key which you want to remain secure + +The best way to do this is to use NodeJS's native environmental variables. + +## Example + +In your `package.json` or directly in a terminal set your variable name and value. + +```bash +env CI=STAGE mocha +``` + +Then in your test or code reference it via `process.env.CI`. e.g. + +```javascript +if (process.env.CI === "STAGE") // do something +``` + +The value is available from anywhere in a spec file allowing you to set values from it before the tests run. e.g. + +```javascript +const URL = `${process.env.APP_HOST}/${process.env.APP_URI}`; +describe('Test the page loads',() { +// tests ... +``` + +Any issues or questions please contact us on Gitter. + +Thanks diff --git a/docs/api-tutorials/jsdoc.tutorials.json b/docs/api-tutorials/jsdoc.tutorials.json index ba7390a3a0..eaf478e470 100644 --- a/docs/api-tutorials/jsdoc.tutorials.json +++ b/docs/api-tutorials/jsdoc.tutorials.json @@ -5,6 +5,12 @@ "custom-reporter": { "title": "Create a Custom Reporter" }, + "environment-variables": { + "title": "Environment variables" + }, + "mess-with-globals": { + "title": "Mess with globals" + }, "related-tools": { "title": "Related tools" }, @@ -14,6 +20,9 @@ "spies": { "title": "Spies" }, + "stub-stdout": { + "title" : "Stub stdout" + }, "tagging": { "title": "Tagging with --grep" }, diff --git a/docs/api-tutorials/mess-with-globals.md b/docs/api-tutorials/mess-with-globals.md new file mode 100644 index 0000000000..d96f48931f --- /dev/null +++ b/docs/api-tutorials/mess-with-globals.md @@ -0,0 +1,55 @@ +# Mess with globals + +Related issue [#1582](https://github.com/mochajs/mocha/issues/1582) + +If your test messes with globals, a reasonable expectation is that you will clean up after yourself. This is not impossible in the case of `process.stdout.write()` or `console.log()`. In fact, it's pretty easy. + +```js +var expect = require('chai').expect; + +describe('my nice test', function() { + var write, log, output = ''; + + // restore process.stdout.write() and console.log() to their previous glory + var cleanup = function() { + process.stdout.write = write; + console.log = log; + output = ""; + }; + + beforeEach(function() { + // store these functions to restore later because we are messing with them + write = process.stdout.write; + log = console.log; + + // our stub will concatenate any output to a string + process.stdout.write = console.log = function(s) { + output += s; + }; + }); + + // restore after each test + afterEach(cleanup); + + it('should suppress all output if a non-AssertionError was thrown', function() { + process.stdout.write('foo'); + console.log('bar'); + // uncomment below line to suppress output, which is bad + // expect(output).to.equal(foobar); + expect(output).to.equal('foobar'); + }); + + it('should not suppress any output', function() { + try { + process.stdout.write('foo'); + console.log('bar'); + // uncomment below line to just throw an AssertionError + // expect(output).to.equal('barfoo'); + expect(output).to.equal(foobar); // ReferenceError + } catch (e) { + cleanup(); + throw e; + } + }); +}); +``` diff --git a/docs/api-tutorials/stub-stdout.md b/docs/api-tutorials/stub-stdout.md new file mode 100644 index 0000000000..ff95f1504b --- /dev/null +++ b/docs/api-tutorials/stub-stdout.md @@ -0,0 +1,31 @@ +# Stub stdout + +If you want to stub stdout inside your own code (via `process.stdout.write` or `console.log`) there is a potential to hinder Mochas reporters output. This is because they rely on the same mechanisms to print results of the tests. + +i.e. + +``` javascript +it('should do, but it do not', function() { + // user wants to hide output generated by console.log calls in fn 'foo' + console.log = function() {}; + foo(); + + expect(...) +}); +``` + +This will result in a faulty reporter output. + +The correct way to handle this is to stub before and restore after the function call. + +``` javascript +it('will do', function() { + var consoleLogStub = sinon.stub(console, 'log'); + foo(); + consoleLogStub.restore(); + + expect(...) +}); +``` + +Now the reporters can run and print the assertion without any interference, while stubbing stdout inside your function.