Pdf.js: 生成(测试)覆盖率统计信息

创建于 2017-07-10  ·  43评论  ·  资料来源: mozilla/pdf.js

要确定我们的代码中未被测试覆盖的部分,或者在实践中没有无效代码,生成覆盖率报告将很有帮助。 另一个用例是在分析特定PDF文件中的问题时快速确定PDF.js的哪些部分是相关的(这对新贡献者尤其有用)。

有多种工具,但是我在https://github.com/gotwarlost/istanbul方面有很好的经验
它可以与Travis集成,并且可以将结果发布到外部服务(如工作服),请参见https://coveralls.io/github/Rob--W/cors-anywhere?branch=master (与https集成: //github.com/Rob--W/cors-anywhere/commit/f9af03e76249b4dd38722b459293773ccddb6c7d)。

PDF.js具有我所知道的不同执行方式(有关更多详细信息,请参见gulpfile.js ):

  • unittestcli-在Node.js中运行PDF.js的一些单元测试(只需最小的源代码更改,仅使用在gulpfile.js中配置的babel
  • unittest-在浏览器中运行PDF.js的一些单元测试(只需最少的源代码更改,仅通过babel进行转译,在systemjs.config.js中配置
  • browsertest-在浏览器中运行测试(我们测试Chrome和Firefox)。 这依赖于generic构建目标创建的二进制文件,该目标使用通过babel转译然后与webpack捆绑在一起的代码(在gulpfile.js中配置)。
  • examples / node / pdf2svg.js-可用于在Node.js上触发SVG渲染后端(取决于generic构建目标,就像browsertest一样)
  • 作为浏览器扩展(Firefox / Chromium),使用firefox / chrome构建目标(使用与通用目标类似的构建过程,只是具有不同的DEFINES)

理想情况下,我们将获取原始资源的覆盖率统计信息,但首先,我们还可以为直接在浏览器/Node.js中运行的生成的JS文件获取覆盖率统计信息(如果更简单的话)。

1-test 5-good-beginner-bug

所有43条评论

unittestcli-在Node.js中运行PDF.js的一些单元测试(只需最少的源代码更改,仅使用babel进行转译)。
browsertest-在浏览器中运行测试(我们测试Chrome和Firefox)。 这依赖于generic构建目标创建的二进制文件,该目标使用通过babel转译然后与webpack捆绑在一起的代码。

请注意,虽然browsertest将运行参考测试,但还有unittest命令在浏览器中运行完整的单元测试集(与unittestcli只运行一个子集的相反)现有的单元测试)。

此外,请注意,如果设置了PDFJS_NEXT构建标记(与gulpfile.js其他构建标记一样,或者作为命令行参数),则可以跳过“使用Babel进行翻译”步骤。 虽然代码仍与Webpack捆绑在一起,但至少可以避免转译步骤。

@ Rob--WI想从事此工作

是你的! 如果您有任何疑问,请告诉我们(最好是在IRC上)。

@timvandermeij我正在考虑使用Karma工具,它与伊斯坦布尔代码覆盖

@ Divya063您能否共享代码,例如通过将当前代码推送到Github上pdf.js分支上的一个分支上? 我想知道在必要时是否正在运行webpack或babel。

您正在使用哪个版本的Node.js?

感谢您的回应,Node版本为6.11.1。 这是分支https://github.com/Divya063/pdf.js/tree/dev的链接

错误是:

的Firefox 43.0.0
SyntaxError:导入声明只能出现在顶层
铬60.0.3112
未捕获的SyntaxError:意外的令牌导入

这表明该代码在使用前未进行转译。 当前,没有在任何浏览器中默认启用对ES模块的内置支持(更多信息),因此需要首先编译代码。

我已经编辑了我的初始文章,指出了在PDF.js的构建系统中配置了转译的位置。 也许您可以尝试使用现有的插件来集成istanbul和babel。 快速搜索显示https://github.com/istanbuljs/babel-plugin-istanbul ,但可能还有其他选择。

(并且Firefox的当前稳定版本为55。您正在使用Firefox 43进行测试,这是古老的,不受支持。建议您先升级到最新版本的Firefox,然后再进行测试)

@ Rob--W感谢您指出错误。我将尽快更新结果。

@ Rob--WI使用karma-browserify转换了代码并升级了firefox版本,但是仍然出现了很多错误,这是分支https://github.com/Divya063/pdf.js/tree的链接

您可以分享错误消息吗?

并且如果可能的话,请尝试使用webpack而不是browserify,因为webpack已经是我们所使用的。 这样做使我们能够检测浏览器中实际使用的代码。

而且我还看到您正在检入.idea和其他特定于用户的项目/ IDE文件。 当您为现有项目做出贡献时,最好不要将不相关的文件添加到该项目中,因为这会使存储库混乱并导致合并冲突。 在最终的拉取请求中,不应包含这些文件。

这个问题还在吗? 如果是,我想继续努力。

是的,随时进行处理。

@timvandermeij
我正在做这个。 我使用过伊斯坦布尔来进行测试,并使用工作服来显示报告。 我已在需要的地方进行了必要的必要更改。 但是,每当我使用

npm run coveralls

我收到以下错误

npm run coveralls

> [email protected] coveralls /home/shikhar/Desktop/mozillaPdfJs/pdf.js
> npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls


> [email protected] cover /home/shikhar/Desktop/mozillaPdfJs/pdf.js
> istanbul cover test/**/*.js "--report" "lcovonly"

Running test 1/16: test_first_run
Running test 2/16: test_first_run_incognito
Running test 3/16: test_storage_managed_unavailable
Running test 4/16: test_managed_pref
Running test 5/16: test_local_pref
Running test 6/16: test_managed_pref_is_overridden
Running test 7/16: test_run_extension_again
Running test 8/16: test_running_for_a_while
Running test 9/16: test_browser_update
Running test 10/16: test_browser_update_between_pref_toggle
Running test 11/16: test_extension_update
Running test 12/16: test_unofficial_build
Running test 13/16: test_fetch_is_supported
Running test 14/16: test_fetch_not_supported
Running test 15/16: test_fetch_mode_not_supported
Running test 16/16: test_network_offline
All tests completed.
No coverage information was collected, exit without writing coverage information
[error] "2017-12-17T11:00:06.112Z"  'error from lcovParse: ' 'Failed to parse string'
[error] "2017-12-17T11:00:06.116Z"  'input: ' ''
[error] "2017-12-17T11:00:06.116Z"  'error from convertLcovToCoveralls'

/home/shikhar/Desktop/mozillaPdfJs/pdf.js/node_modules/coveralls/bin/coveralls.js:18
        throw err;
        ^
Failed to parse string
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] coveralls: `npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] coveralls script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/shikhar/.npm/_logs/2017-12-17T11_00_06_136Z-debug.log

我试图在这里这里查找,但无济于事。 有什么问题的帮助吗?

不看代码就很难分辨。 您能否将代码推送到分支,以便此处的贡献者可以与您一起查看?

@timvandermeij在这里。 请忽略gem文件。 我已经删除了。

任何评论@timvandermeij

从一点谷歌搜索看来,这个错误意味着coveralls没有获取lcov格式的数据。 您可以检查npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls中的各个命令是否实际上返回了您期望的结果。

@timvandermeij
当前的主要问题是此语句
No coverage information was collected, exit without writing coverage information
因此,lcov文件始终保持空白,因此发生了这种情况

[error] "2017-12-17T11:00:06.112Z"  'error from lcovParse: ' 'Failed to parse string'
[error] "2017-12-17T11:00:06.116Z"  'input: ' ''
[error] "2017-12-17T11:00:06.116Z"  'error from convertLcovToCoveralls'

在谷歌搜索中,这些似乎是非常常见的错误。 而错误基本上在于伊斯坦布尔。 我尝试在同一版本的不同版本之间切换,但错误不断发生。 但是,在所有地方,测试都是通过摩卡而不是皮棉或单元测试等完成的,因此大多数(几乎)分辨率也仅适用于摩卡。 这些是我查到的一些资料

https://github.com/gotwarlost/istanbul/issues/262
https://github.com/coryhouse/react-slingshot/issues/245
https://github.com/gotwarlost/istanbul/issues/496
和其他几个也没有,但实际上没有一个帮助:(

该版本在travis( https://travis-ci.org/shikhar-scs/pdf.js/jobs/318422621 )上传递,但是仍然没有生成覆盖率。

我不太确定为什么会这样,但是我也发现很多人都通过Jasmine成功地做到了这一点,所以这一定是可能的。 您能否尝试https://bryce.fisher-fleig.org/blog/setting-up-istanbul-with-jasmine/index.html为您工作? 首先,只需尝试这些确切的步骤以查看是否可以独立运行,然后尝试将其集成到PDF.js中。

@timvandermeij就可以了
现在终于生成覆盖率报告。 但是我需要进行转换,然后进行测试,因为它显示了导入和导出语句的问题
Transformation error for /home/shikhar/Desktop/mozillaPdfJs/pdf.js/web/ui_utils.js ; return original code 'import' and 'export' may appear only with 'sourceType: "module"' (16:0)
每个js文件都会出现此错误,我将对其进行处理并尽快提交PR。

@timvandermeij

它们是:构建传递并要求覆盖

覆盖率报告

但是,由于存在导入和导出语句,即使到达这些文件之后,它们也没有经过全面测试,因此我们得到的覆盖率报告为0%。 据我所知,我需要在进行茉莉花测试之前将这些文件添加到ES6,事实证明这是一个问题。 如何为茉莉花提供ES6代码?
我可以按此处http://jpsierens.com/use-es6-right-now/所述更改gulp文件吗?

您确实越来越接近解决方案。 从覆盖率报告来看,您似乎在lib文件上运行了覆盖率,该文件应该已经转换为ES6(请参阅https://github.com/mozilla/pdf.js/blob/6ac9e1c5ed0d5f067872b8482724c171c79566b2/gulp文件。 js#L965和https://github.com/mozilla/pdf.js/blob/6ac9e1c5ed0d5f067872b8482724c171c79566b2/gulpfile.js#L985)。 还是单元测试本身没有移植的问题? 我不太了解它的确切工作原理,但是如果是这种情况,则可能需要对单元测试的Gulpfile进行一些更改。

@timvandermeij

还是单元测试本身没有移植的问题? 我不太了解它的确切工作原理,但是如果是这种情况,则可能需要对单元测试的Gulpfile进行一些更改。

问题是我在错误的文件夹中运行测试。 build>lib文件夹已经包含ES6格式的整个项目,我现在更正了整个内容,即茉莉花和工作服的路径。
另一个问题是--report lcovonly语句。 神奇的是(我真的不知道为什么),当我从工作服系列中删除此部分时,报告开始生成。

您可以检查npm中的各个命令是否覆盖---report lcovonly && cat ./coverage/lcov.info | 工作服实际上会返回您期望的结果。

感谢您指出这一点。

最后,我们能够生成报告:tada:,尽管它们看起来有些难过,但读取确切的文件将使您知道为什么-

  1. 所有未执行的条件语句都被视为“未涵盖”。
  2. 所有未执行的赋值语句也被视为“未涵盖”。

我显然还没有上传自己生成的报告,但是将它们托管在http://pdfjscoveragereport.bitballoon.com上的链接上。 请访问这些链接,您将获得准确的报告。

但是,这些结果未反映在coveralls.io :哭:我不知道为什么。 此外,我注意到即使多次提交coveralls仍在基于非常旧的提交而不是基于最近的提交来构建我的项目,因为尽管生成了覆盖,但始终保持为0(即使现在不是0)。 请帮助我解决该问题。

但是npm run coveralls仍然会以这种格式提供位于build/lib/coverage/lcov-report文件夹中的整个覆盖率报告。

我希望所有这些最终对您有所帮助,但是,我们的最后一个问题是在工作服上以某种方式显示这些报告。

这是我最新版本的链接。 https://travis-ci.org/shikhar-scs/pdf.js
这是我最近提交的链接。

除了没有在Coveralls.io上生成报告之外,我想一切都很好。 因此,我是否会生成PR,因为它会引起更多人的关注,并且可能会更早解决此问题?

干得好! 了解覆盖范围真的很不错,报告最终给了我们这一点。 实际上,它清楚地表明我们需要更多的单元测试,但是报告中确实显示了我们最近添加的单元测试的所有方法,因此看起来非常好。

我确实想知道是否有可能对源文件而不是生成的文件运行coverage。 这使它更容易理解,因为现在在http://pdfjscoveragereport.bitballoon.com/lib/display/metadata.js.html上,我看到第28行没有覆盖,虽然这不是我们的代码,而是自动生成的代码。 如果发现很难,我们可以将当前方法作为第一个版本,并在后续问题中进行。

因此,我是否会生成PR,因为它会引起更多人的关注,并且可能会更早解决此问题?

是的,那是个好主意。 然后,我们可以开始审核过程,看看还有哪些问题要解决。

了解覆盖范围真的很不错,报告最终给了我们这一点。 实际上,它清楚地表明我们需要更多的单元测试,但是报告中确实显示了我们最近添加的单元测试的所有方法,因此看起来非常好。

虽然我们确实可以进行更多的单元测试,但是可悲的是,大部分代码库可能仅凭单元测试就无法达到“良好”的测试覆盖率。

https://github.com/mozilla/pdf.js/issues/8632#issue -241690851所述,这里有一些不同的测试套件,除非我错误地从gulp browsertest获取覆盖率结果,真正了解我们实际的测试覆盖范围是几乎必不可少的。

@snuffleupagus @timvandermeij

今天早上,我广泛尝试使用语句cd build && cd lib && istanbul cover --include-all-sources jasmine-node test在所有文件夹中查找覆盖率报告,使用cd <directory name>更改不同目录,并使用jasmine-node <directory names and js files>但徒劳。

尽管有时会(并非总是)生成测试报告,但这是由于特定目录中存在一个或两个ES6格式的js文件而引起的(这仅带来覆盖率报告的2-3%)。 可悲的是,任何包含import or export statements js文件都将以这种格式返回错误。

Transformation error for /home/shikhar/Desktop/mozillaPdfJs/pdf.js/src/core/arithmetic_decoder.js ; return original code 'import' and 'export' may appear only with 'sourceType: "module"' (183:0) Unable to post-instrument: /home/shikhar/Desktop/mozillaPdfJs/pdf.js/src/core/arithmetic_decoder.js

并且由于该错误,根本不会检查文件的覆盖范围,因此将返回0%的报告。

我确实想知道是否有可能对源文件而不是生成的文件运行coverage。

再次,源文件夹包含具有导入和导出语句的文件,因此发生上述错误,因此根本不检查相关文件,从而导致覆盖率为0%。

因此,必须在build文件夹本身中进行测试。

从gulp浏览器测试中获取覆盖率结果对于真正了解我们实际的测试覆盖范围是至关重要的。

@Snuffleupagus这些特定测试在哪里? 我们可以尝试使用上面提到的jasmine-node语句直接测试它们。

如果发现很难,我们可以将当前方法作为第一个版本,并在后续问题中进行。

是的,我们宁愿那样做。

是的,那是个好主意。 然后,我们可以开始审核过程,看看还有哪些问题要解决。

当然,我将从这一点开始。

#9308的PR仅显示了单元测试的测试范围示例。 生成的报告几乎没有价值,因为我们的单元测试集很小。 有关更多详细信息,请参见https://github.com/mozilla/pdf.js/pull/9308#issuecomment -353588039

因此,要获得浏览器测试,我们需要:

  1. 一种生成覆盖率数据的方法。
  2. 一种检索覆盖率数据(并将其上传到工作服的方法)。

要解决1),应编辑gulpfile.js以选择添加代码工具,该工具将在浏览器中导出到window.__coverage__对象。 gulp-istanbul可能有用。 该文档似乎很少,但是我在https://stackoverflow.com/questions/38208735/no-window-coverage-object-is-created-by-istanbul-phantomjs找到了一个示例

完成第1步后,浏览器测试将具有window.__coverage__变量(或您在coverageVariable配置参数中输入的任何变量)。 要获取覆盖率报告:

  1. 修改测试运行程序(https://github.com/mozilla/pdf.js/blob/e081a708c36cb2aacff78890488637637fcf23671/test/driver.js),将包含XMLHttpRequest的覆盖结果发布到测试服务器。
  2. 在测试服务器(https://github.com/mozilla/pdf.js/blob/e081a708c36cb2aacff7889048863723fcf23671/test/test.js)中,注册一个新的钩子以接收测试结果,并使用fs将其写入文件。
  3. 将报告上传到工作服(例如,使用“ coveralls”命令,如#9308所示)。

@ Rob--W感谢您的详细审查。 我会跟进并尽快还原。

此评论提供了实现的技巧,并解决了https://github.com/mozilla/pdf.js/pull/9308#issuecomment -353710595的问题

istanbul仅将检测添加到代码中。 此输入被认为是可执行代码,因为“工具”意味着添加额外的JavaScript代码,以检测执行何时通过该行,语句等。如果在添加工具后再次对代码进行了重大更改,则结果覆盖率报告将变得毫无意义。

可以在程序运行时即时执行此检测(例如,从命令行运行istanbul coveristanbul将拦截对Node.js的require调用)在加载模块之前用工具转换代码),或与执行分开使用(例如,如博客文章所示:在命令行生成工具代码,在浏览器中执行代码)。

在您当前在#9308的PR中,您正在以jasmine作为要运行的程序来调用istanbul cover 。 正如我之前提到的,效果类似于运行gulp unittestcli -即测试是针对build/lib目录中的预构建库运行的(在test/unit/clitests.json ) 。 这就解释了为什么您的覆盖率报告显示除build/lib/之外的所有其他项的覆盖率为0(因为build/libbuild/streams/只有require -d(Node.js)模块) build/streams/ -请参阅gulp unittestcli任务定义的结尾)。

为了获得有用的覆盖率报告,覆盖率报告最好在模块级别。 这是前进的一步:您需要将istanbul集成到构建管道中,以便从ES6转换代码时会添加检测。 在那之后,生成每个模块的报告变得更加困难(但并非没有可能,理论上源映射提供了足够的信息以将数据映射到原始文件)。
这是一个挑战,需要充分了解如何使用Babel,gulp,istanbul和源地图/模块(我已经在源代码中提到了相关位置,其中PDF.js将所有模块组合在一起以生成PDF.js。库-参见#8632)。 这些知识非常有用,因此,如果您不怕挑战,可以在我的指导下进行探索。

但是,在深入探讨之前,让我们从一个简单的事情开始:从浏览器获取覆盖率报告。 我们有两种在浏览器中运行测试的方式, unittestbrowsertest 。 由于我们已经有了在Node.js中运行单元测试的相当简单的方法,因此让我们关注browsertest 。 浏览器测试不使用单个模块,而是使用generic gulp目标创建的PDF.js库,位于GENERIC_DIR ,也称为build/generic/ 。 因此,只需在build/generic添加代码工具即可。 我建议将build/generic/作为输入目录,并将结果写入coverage/build/generic

之后,您需要更改test/test_slave.html以无条件地在<script>标记中加载../build/generic/build/pdf.js ,但有条件地加载../build/generic/build/pdf.js../coverage/build/generic/build/pdf.js取决于一些配置参数(为了进行测试,您可以仅硬编码后一个URL,稍后在完成将覆盖率报告发送回测试服务器这一更困难的任务之后,很容易更改此硬编码参数) 。

将正常的pdf.js库替换为已检测的pdf.js库后,覆盖率统计信息将在测试运行时生成。 结果存储在全局window.__coverage__变量中。 浏览器中的测试驱动程序完成后( test / driver.js中的_quit方法),您可以序列化此报告(例如,使用JSON.stringify(window.__coverage__) ),并将其与XMLHttpRequest一起发送到服务器。 driver.js文件中的其他位置-确保在发送/tellMeToQuit消息之前将报告发送到服务器,否则可能不会发送覆盖率报告正确)。
您可以在https://github.com/mozilla/pdf.js/blob/ba5dbc96326518ad716158ef040f61794cc72202/test/test.js中为新的自定义API调用添加新的处理程序。 对于代码示例,看看XMLHttpRequest在呼叫driver.js (如/tellMeToQuit消息),并且发现在相应的处理程序test.js 。 在服务器端收到序列化的JSON后,请使用fs.writeFileSync API将覆盖率报告写入文件(同样, test.js中还有其他示例显示了如何写入文件) 。

@ Rob--W我要等到新一年才能上班...在那之后我一定会继续前进

之后,您需要更改test / test_slave.html以不无条件地将../build/generic/build/pdf.js加载到

之后,您需要更改test / test_slave.html以不无条件地将../build/generic/build/pdf.js加载到

@ Rob--WI确实设法在tests.js创建了一个类似的参数(通过模仿testFilter参数),但是,将其合并到test/test_slave.html中对我来说仍然是一个问题。 对于其余的更改,请再次访问PR,我已提交新的提交。 #9308

另外,如果您可以为我提供加入IRC频道的链接或pdf.js特有的松弛/干扰/邮件列表。

@ Rob--W问题仍然存在吗? 如果是,我想继续努力。
谢谢。

第一次尝试是在#9308中,因此您可以以此为灵感。 让我们集中精力让最小版本起作用,即仅在本地起作用的版本。 它不需要在机器人或Travis CI上工作; 如果我们可以在本地制作覆盖率报告,那已经非常重要了。 对于本地而言,最好创建一个名为gulp coverage的命令,该命令运行检测的单元测试并基于该命令生成覆盖率报告。 它正在工作并合并在一起,我们可以随时对此进行迭代。

@timvandermeij仍然活跃吗? 我也可以去

是的,随时进行处理! 我们应该从简单开始; 有关可能的方法,请参见https://github.com/mozilla/pdf.js/issues/8632#issuecomment -455868037。

@timvandermeij想知道我是否可以gulp任务?

我对gulp不太熟悉,但是我愿意知道这是否是必需的

我认为没有人在为此工作,所以继续吧! 对于初始补丁,保持简单很重要。 由于我们使用Gulp作为主要工具,因此首选使用它,但是我们也欢迎其他建议。 有关实现思路,请参阅https://github.com/mozilla/pdf.js/issues/8632#issuecomment -455868037。 尽管Gulp是一个相当简单的任务运行程序,但是它不需要Gulp的大量经验,即,它几乎包装了您在NPM脚本中也可以做的任何事情。 看一下Gulpfile可以得到一些启发。

我想为此工作。 问题仍然存在吗? 在哪里可以更好地理解该错误?

@jezhou正在

非常感谢您的更新。 我想我可以开始工作了吗? 哪里
我可以获得更多信息吗? 关于这个问题和它的其余部分?

2020年5月16日星期六,下午5:56罗布·吴, notifications @ github.com写道:

@jezhou https://github.com/jezhou正在研究这个问题,并做了一些
#11580 https://github.com/mozilla/pdf.js/pull/11580中的进度。 公关
最近尚未更新。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/mozilla/pdf.js/issues/8632#issuecomment-629637879
或退订
https://github.com/notifications/unsubscribe-auth/AKUZ65CGSIZF6OMFZWENWF3RR2A77ANCNFSM4DSK7SGQ

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

xingxiaoyiyio picture xingxiaoyiyio  ·  3评论

patelsumit5192 picture patelsumit5192  ·  3评论

brandonros picture brandonros  ·  3评论

hp011235 picture hp011235  ·  4评论

liuzhen2008 picture liuzhen2008  ·  4评论