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

ts-junit

v1.0.18

Published

use junit descrator with typescript

Downloads

215

Readme

ts-junit

use JUnit 5 Decrator with TypeScript

在我看来,在TypeScript里使用面向对象是很大概率变成最常用的方式的。目前所有的JavaScript测试都是面向过程的,比如qunit、jest、mocha、ava、tape等测试框架实现,还是围绕在面向过程阶段。我以为这不是TypeScript在现实中该有的样式。

我对Java还算熟悉,比如使用JUnit 5的测试代码就是采用面向对象写法的,代码如下。

import static org.junit.jupiter.api.Assertions.assertEquals;

import example.util.Calculator;

import org.junit.jupiter.api.Test;

class MyFirstJUnitJupiterTests {

    private final Calculator calculator = new Calculator();

    @Test
    void addition() {
        assertEquals(2, calculator.add(1, 1));
    }

}

这种写法是非常简单的,这就是Java面向的好处。如果换成TypeScript,几乎可以保持写法一模一样,代码如下。


import assert from 'assert'
import { Test } from 'ts-junit'

export default class MyFirstJUnitJupiterTests  {

  calculator = new Calculator();

  @Test
  void addition() {
    assert.is(2, calculator.add(1, 1));
  }

}

反观前端的测试代码基本上2种风格。前端的测试代码风格1,它是最常用的测试方式,代码实例如下。

test('JSON', () => {
  const input = {
    foo: 'hello',
    bar: 'world'
  };

  const output = JSON.stringify(input);

  assert.snapshot(output, `{"foo":"hello","bar":"world"}`);
  assert.equal(JSON.parse(output), input, 'matches original');
})

前端的测试代码风格2,bdd风格,它更强调行为对测试用例的影响,代码实例如下。

describe('User', function(){
  describe('#save()', function(){
    it('should save without error', function(done){
      var user = new User('Luna');
      user.save(function(err){
        if (err) throw err;
        done();
      });
    })
  })
})

对比一下Java和JavaScript测试多个写法之后,你会发现,面向对象在JavaScript(TypeScript)里根本不是一等公民。于是我就蒙发了一个想法,想用TypeScript实现一下JUnit。

特性

  • ~~jest 支持 ts 需要引入babel~~
  • ~~ts-jest 直接支持ts,测试语法上是jest语法,suite/test或describe/it~~
  • ts-junit 使用junit 5的装饰器进行封装,成熟,使用于熟悉OO的开发,尤其对Java开发更友好。
  • ts-junit 默认使用uvu,同时提供各个常见测试框架的支持,比如jest、mocha、ava、tape、qunit、jasmine等。

示例

import assert from 'assert'
import { BeforeAll, BeforeEach, Disabled, Test, AfterEach, AfterAll } from 'ts-junit'

export default class MyFirstJUnitJupiterTests {
    calculator = new Calculator()

    @BeforeAll
    static void initAll() {
    }

    @BeforeEach
    void init() {
    }

    @Test
    void succeedingTest() {
    
    }

    @Test
    void failingTest() {
        assert.fail("a failing test");
    }

    @Test
    @Disabled("for demonstration purposes")
    void skippedTest() {
        // not executed
    }

    @Test
    void abortedTest() {
        assert.assumeTrue("abc".contains("Z"));
        assert.fail("test should have been aborted");
    }

    @AfterEach
    void tearDown() {
    }

    @AfterAll
    static void tearDownAll() {
    }
}

Usages

方式1: 使用独立cli进行编译

不依赖当前项目的ts环境,直接通过cli执行,参考源码中tests目录下的文件。

$ npm i --global ts-juint
$ junit tests
$ junit tests/test.ts

编写第一个测试用例

import assert from 'assert'
import { Test } from 'ts-junit'

export default class MyFirstJUnitJupiterTests  {

    calculator = new Calculator();

    @Test
    void addition() {
        assert.is(2, calculator.add(1, 1));
    }

}

方式2: 依赖当前项目的ts环境进行编译

$ npm i --save-dev ts-juint

编写测试入口文件ts-junit.ts,文件内指定测试文件或测试目录即可。

import * as path from "node:path";
import { run } from "ts-junit";

const folder = path.resolve(process.cwd(), "./tests");
const file = path.resolve(process.cwd(), "./tests/test.ts");

run([folder, file]);

创建编译时的 tsconfig.json 文件

{
  "compileOnSave": true,
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./build",
    "rootDir": "./src",
    "typeRoots": [],
    "types": [],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "exclude": ["node_modules"],
  "include": ["./src/**/*.ts", "./test/**/*.ts"]
}

编辑 package.json 的启动和编译脚本

{
  "scripts": {
    "test": "NODE_ENV=dev ts-node --project tsconfig.json --files ts-junit.ts",
    "build": "tsc"
  }
}

启动服务

$ npm test
> NODE_ENV=dev ts-node --project tsconfig.json --files ts-junit.ts
[2020-9-1 19:52:12] [debug] [init] [router] get - /

装饰器

  • 参考junit5的文档 https://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations
  • 进度 7/20

TODO

1) 结合 https://github.com/midwayjs/injection 更简单(暂未实现)

class Test {
  @Inject()
  helloTest: IHelloTest;
  @Inject()
  helloService: IHelloService;

  @Before()
  before() {
    mock(helloTest, 'sayhello', () => {
      return 'mocked'
    });
  }

  @Test()
  async test() {
    expect(this.helloTest.sayhello()).eq('mocked');
    
    expect(this.helloService.sayhello('test')).eq('hello test');
  }
}

2) use vm2 with require from memfs