{"id":16832692,"url":"https://github.com/zswang/examplejs","last_synced_at":"2025-03-22T04:30:41.529Z","repository":{"id":143878525,"uuid":"58908812","full_name":"zswang/examplejs","owner":"zswang","description":"A tool for converting example code into test cases","archived":false,"fork":false,"pushed_at":"2017-05-07T14:41:33.000Z","size":35,"stargazers_count":44,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-25T16:41:21.089Z","etag":null,"topics":["jsdoc","unittest"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zswang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-16T06:25:05.000Z","updated_at":"2024-06-19T13:27:36.717Z","dependencies_parsed_at":null,"dependency_job_id":"4d1a4f86-b681-46e9-8e3f-950dd33aac1a","html_url":"https://github.com/zswang/examplejs","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zswang%2Fexamplejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zswang%2Fexamplejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zswang%2Fexamplejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zswang%2Fexamplejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zswang","download_url":"https://codeload.github.com/zswang/examplejs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244907420,"owners_count":20529850,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jsdoc","unittest"],"created_at":"2024-10-13T11:50:04.988Z","updated_at":"2025-03-22T04:30:41.215Z","avatar_url":"https://github.com/zswang.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"如何优雅地写测试用例？\n----------\n\n# [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][coverage-image]][coverage-url]\n\n## 背景\n\n做好单元测试是保证代码质量的有效手段。这里介绍一种用示例代码转为测试用例的工具。\n这样做可以降低写测试用例的学习和使用成本。\n\n## 思路\n\n通常在示例代码中我们会用注释给出一个输出预判。\n\n```js\nvar a = 1;\nvar b = 2;\nconsole.log(a === b); // false\n```\n\n这样方便复制到控制台编辑运行。\n\n如果写测试用例就会这样：\n```js\nvar a = 1;\nvar b = 2;\nassert.equal(a === b, false);\n```\n\n可以看出来：示例代码和测试代码都有一个输出预判！\n\n那么为何不能用示例代码写测试用例呢？也就是做一下简单的转换即可。\n\n只要做简单的约定就能达到，分别是：\n\n* 示例代码块\n* 输出预判\n* 异步完成\n* 异常预判\n\n## 方法\n\n### 定义示例代码块\n\n`jsdoc` 中用 @`example` 标记，例如：\n\n```js\n/**\n * @example xxyy\n * var a = 1;\n * var b = 2;\n * console.log(a === b); // false\n */\n```\n\n但这种每行都有 `*` 的代码，复制粘贴后还需要清理一次，所以我倾向于这种:\n\n```js\n/**\n * @example xxyy\n  var a = 1;\n  var b = 2;\n  console.log(a === b); // false\n */\n```\n\n为区分运行环境，所以得指定语言，如：\n\n    /**\n     * @example xxyy\n      ```js\n      var a = 1;\n      var b = 2;\n      console.log(a === b); // false\n      ```\n     */\n\n\n## 约定\n\n### 输出预判\n\n![image](https://cloud.githubusercontent.com/assets/536587/15286345/02c42cde-1b8f-11e6-9a01-562418199de4.png)\n\n    /**\n     * @example 表达式相等预判\n      ```js\n      var a = 1;\n      var b = 2;\n      console.log(a === b);\n      // \u003e false\n      ```\n     */\n\n    /**\n     * @example 表达式结果预判\n      ```js\n      var a = 1;\n      var b = 2;\n      console.log(a + b);\n      // \u003e 3\n      ```\n     */\n\n\n    /*\n     * @example 表达式类型预判\n      ```js\n      var a = 1;\n      console.log(JSON.stringify(a + '1'));\n      // \u003e \"11\"\n      ```\n     */\n\n### 批量输出预判\n\n![image](https://cloud.githubusercontent.com/assets/536587/15286346/09169450-1b8f-11e6-8087-a0f8c4489b56.png)\n\n\n    /*\n     * @example 批量表达式预判\n      ```js\n      for (var i = 0; i \u003c 5; i++) {\n        console.log(i);\n      }\n      // \u003e 0\n      // \u003e 1\n      // \u003e 2\n      // \u003e 3\n      // \u003e 4\n      ```\n     */\n\n### 异步完成\n\n![image](https://cloud.githubusercontent.com/assets/536587/15286354/0f2f9710-1b8f-11e6-88d8-37e2a0055d5c.png)\n\n\n    /*\n     * @example 异步执行预判\n      ```js\n      var a = 1;\n      setTimeout(function () {\n        console.log(a);\n        // \u003e 2\n        // * done\n      }, 1000);\n      a++;\n      ```\n     */\n\n### 异常预判\n\n![image](https://cloud.githubusercontent.com/assets/536587/15286361/13b9ec68-1b8f-11e6-8839-d61ccaefbf23.png)\n\n    /*\n     * @example 异常执行预判\n      ```js\n      var a = JSON.parse('#error');\n      // * throw\n      ```\n    */\n\n### 浏览器环境\n\n    /*\n     * @example 浏览器环境\n      ```html\n      \u003cdiv\u003e\u003c/div\u003e\n      ```\n      ```js\n      console.log(document.querySelector('div') !== null);\n      // \u003e true\n      ```\n     */\n\n### jQuery\n\n![image](https://cloud.githubusercontent.com/assets/536587/17015910/2a5873f0-4f5f-11e6-9f52-e208e671b775.png)\n\n    /*\n     * @example jQuery\n       ```css\n       .red {\n         background-color: red;\n       }\n       ```\n       ```html\n       \u003cdiv class=\"red\"\u003e\u003c/div\u003e\n       \u003cscript src=\"https://code.jquery.com/jquery-3.1.0.min.js\"\u003e\u003c/script\u003e\n       ```\n       ```js\n       $(function () {\n         console.log($('.red').css('background-color'));\n         // \u003e red\n         // * done\n       })\n       ```\n     */\n\n\n## 使用方法\n\n### 安装\n\n```bash\n$ npm install examplejs -g\n```\n\n### 运行\n\n```bash\n$ examplejs main.js -o test/main.test.js\n```\n\n### Gulp\n\n```js\nvar examplejs = require('gulp-examplejs');\n\ngulp.task('example-js', function() {\n  return gulp.src('src/**.js')\n    .pipe(examplejs({\n      head: 'head.js'\n    }))\n    .pipe(gulp.dest('test'));\n});\n```\n\n## License\n\nMIT © [zswang](http://weibo.com/zswang)\n\n[npm-url]: https://npmjs.org/package/examplejs\n[npm-image]: https://badge.fury.io/js/examplejs.svg\n[travis-url]: https://travis-ci.org/zswang/examplejs\n[travis-image]: https://travis-ci.org/zswang/examplejs.svg?branch=master\n[coverage-url]: https://coveralls.io/github/zswang/examplejs?branch=master\n[coverage-image]: https://coveralls.io/repos/zswang/examplejs/badge.svg?branch=master\u0026service=github\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzswang%2Fexamplejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzswang%2Fexamplejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzswang%2Fexamplejs/lists"}