npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

packtester

v0.2.1

Published

Assert your published package actually works

Downloads

8

Readme

packtester

Assert your published package actually works

Motivation

Running your regular test suite (e.g., npm test) in CI will miss packaging-related issues, such as missing files and package exports.

There's no staging registry you can test with, so when something's published, it's published. If there's a problem with it, you have to issue a patch and publish again. We can't avoid the problem entirely, but packtester gets us closer.

This is kind of a pain to setup manually, so automating it might be nice, right?

Install

$ npm install packtester --save-dev

Setup (Automatic)

TODO: via init command; needs implementation

Setup (Manual)

Add a pretest script to your scripts field in package.json:

{
  "scripts": {
    "pretest": "packtester",
    "test": "my-regular-test-script"
  }
}

It's recommended to also run packtester during prepublishOnly, so it will check at the last minute before you publish.

Create a __pack_tests__ directory. All files (with .js, .cjs, and .mjs extensions, by default) in this directory will be run with your module installed as a dependency. Here's an example file:

// packtester.packtest.js

const assert = require('assert');
// remember, use your package like a consumer would
const pkg = require('packtester/package.json'); // yeah yeah I know

let packtester;
assert.doesNotThrow(() => {
  packtester = require(pkg.name);
}, `could not require('${pkg.name}')`);

// packtester exports a function, `packTest`
assert.ok(
  typeof packtester.packTest === 'function',
  'did not export "packTest" function'
);

// ESM!
assert.doesNotReject(import(pkg.name), `could not import('${pkg.name}')`);

assert.doesNotThrow(() => {
  require(`${pkg.name}/${pkg.main}`);
}, `could not require('${pkg.name}/${pkg.main}') directly`);

You do not need to add test files for packtester to your published package (unless you want to); in other words, they don't need to be in the files prop of package.json and/or can be added to .npmignore, if desired.

Suggested CI Configuration

Run packtester as a job or step before the main test suite (e.g., npm test) as a "smoke test," and have subsequent steps wait for this to complete successfully.

GitHub Actions Example

Add a smoke-test script to package.json (remove the "pretest": "packtester" script, if present):

{
  "scripts": {
    "smoke-test": "packtester",
    "test": "your-test-command"
  }
}

And in your workflow file (e.g., .github/workflows/my-workflow.yml):

jobs:
  smoke-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: bahmutov/npm-install@v1
      - name: Smoke Test
        run: npm run smoke-test
  test:
    runs-on: ubuntu-latest
    needs: smoke-test
    steps:
      - uses: actions/checkout@v2
      - uses: bahmutov/npm-install@v1
      - name: Full Test Suite
        run: npm test

Options

Custom Targets

By supplying positional arguments to packtester, you can point it at any directory, file, or glob. Example:

{
  "scripts": {
    "pretest": "packtester \"my-smoke-tests/**/*.js\"",
    "test": "my-regular-test-script"
  }
}

Custom package.json

packtester needs the package.json of your package to run. Use the --package <package.json> command-line option to use a specific package.json file. This may be useful in a monorepo or workspace. Example:

{
  "scripts": {
    "pretest": "packtester --package=./packages/subpackage/package.json",
    "test": "my-regular-test-script"
  }
}

More Help

Run npx packtester --help to see more usage options.

API

packtester exports a single property, packTest, which is an async function.

packtester.packTest([opts]): Promise<void>

Does everything the packtester CLI does.

opts is an options object and supports properties (all optional):

  • {string|string[]} target - One or more target files, dirs, globs. Defaults to __pack_tests__
  • {string} cwd - Current working directory
  • {PackageJson} pkg - A parsed package.json
  • {string} npmPath - Path to npm executable
  • {number} logLevel - Log level, 0-5, with 0 being "error" and 5 being "trace"

About Tests

The purpose of these tests is to make assertions about the state of your package's public API. The question you're trying to answer is this: is my package usable when installed via a package manager?

Remember: you won't have your devDependencies installed; this means no test frameworks, assertion libraries, etc. The built-in assert module works well for this use case.

ESM Example

TODO

How It Works

packtester:

  1. Runs npm pack on your project to generate a tarball in a temporary directory
  2. Runs npm install against the tarball in the temp dir
  3. Copies the target tests into temp dir
  4. Runs the target tests, exiting with non-zero code if they fail
  5. Removes the temp dir

By installing from a tarball created from npm pack, we simulate what would happen if you installed your project via a package manager, e.g., npm install my-package.

License

Copyright © 2020 Christopher Hiller. Licensed Apache-2.0