简体   繁体   English

如何生成浮点逻辑的良好代码覆盖?

[英]How to generate good code coverage of floating-point logic?

I am hand-crafting new code. 我正在手工制作新代码。 I'd like to make sure I leave no stone unturned. 我想确保我不遗余力。

Is there anything specific I can do beyond specifying Code Contracts to guide Pex so it produces good coverage in numerically-intensive code? 除了指定代码合同以指导Pex之外,我还能做些什么吗?所以它在数字密集型代码中产生了良好的覆盖范围?

Try searching http://research.microsoft.com/en-us/projects/pex/pexconcepts.pdf for keyword 'float' for some background information. 尝试在http://research.microsoft.com/en-us/projects/pex/pexconcepts.pdf中搜索关键字“float”以获取一些背景信息。

Arithmetic constraints over floating point numbers are approximated by a translation to rational numbers, and heuristic search techniques are used outside of Z3 to find approximate solutions for floating point constraints. 浮点数的算术约束通过对有理数的转换来近似,并且在Z3之外使用启发式搜索技术来找到浮点约束的近似解。

...and also... ...并且...

Symbolic Reasoning . 符号推理 Pex uses an automatic constraint solver to determine which values are relevant for the test and the code-under-test. Pex使用自动约束求解器来确定哪些值与测试和被测代码相关。 However, the abilities of the constraint solver are, and always will be, limited. 但是,约束求解器的能力是,并且总是会受到限制。 In particular, Z3 cannot reason precisely about floating point arithmetic. 特别是,Z3不能精确地推理浮点运算。

Alternatively, do you know a tool under .NET that is better suited for the task of finding numerical anomalies under .NET? 或者,您是否知道.NET下的工具更适合在.NET下查找数字异常的任务? I am aware of http://fscheck.codeplex.com/ but it does not perform symbolic reasoning. 我知道http://fscheck.codeplex.com/但它不执行符号推理。

Is what you want good coverage? 你想要什么好的报道? Just having a test that runs every branch in a piece of code is unlikely to actually mean that it is correct - often it's more about corner cases and you as the developer are best placed to know what these corner cases are. 只需要在一段代码中运行每个分支的测试实际上不太可能意味着它是正确的 - 通常更多的是关于极端情况,并且您作为开发人员最好知道这些角落案例是什么。 It also sounds like it works by just saying 'here's an interesting input combination' whereas more than likely what you want is to specify the behaviour of the system you want to see - if you have written the code wrong in the first place then the interesting inputs may be completely irrelevant to the correct code. 它听起来像只是说“这是一个有趣的输入组合”,而你想要的更多可能是指定你想要看到的系统的行为 - 如果你在第一时间编写错误的代码然后有趣的话输入可能与正确的代码完全无关。

Maybe this isn't the answer you're looking for but I'd say the best way to do this is by hand! 也许这不是您正在寻找的答案,但我想说最好的方法就是手工制作! Write down a spec before you start coding and turn it in into a load of test cases when you know/as you are writing the API for your class/subsystem. 在开始编码之前记下规范,并在知道/为您的类/子系统编写API时将其转换为大量测试用例。

As begin filling out the API/writing the code you're likely to pick up extra bits and pieces that you need to do + find out what the difficult bits are - if you have conditionals etc that are something you feel that someone refactoring your code might get wrong then write a test case that covers them. 当开始填写API /编写代码时,你可能需要做一些额外的部分操作+找出困难的部分 - 如果你有条件等等你觉得有人重构你的代码可能会出错,然后写一个涵盖它们的测试用例。 I sometimes intentionally write code wrong at these points, get a test in that fails and then correct it just to make sure that the test is checking the correct path through the code. 我有时故意在这些点上编写错误的代码,然后进行测试失败然后纠正它只是为了确保测试正在通过代码检查正确的路径。

Then try and think of any odd values you may not have covered - negative inputs, nulls etc. Often these will be cases that are invalid and you dont want to cater for/have to think about - in these cases I will generally write some tests to say that they should throw exceptions - that basically stops people misusing the code in cases you haven't though about properly/with invalid data. 然后尝试思考你可能没有涵盖的任何奇数值 - 负输入,空值等。通常这些都是无效的情况,你不想满足/不得不考虑 - 在这些情况下我会写一些测试要说他们应该抛出异常 - 这基本上会阻止人们在没有正确/无效数据的情况下滥用代码。

You mentioned above that you are working with numerically intensive code - it may be worth testing a level above so you can test the behaviours in the system you are looking for rather than just number crunching - presuming that the code isn't purely numerical this will help you establish some real conditions of execution and also ensure that whatever the number crunching bit is actually doing interacts with the rest of the program in the way you need it to - if it's something algorithmic you'd probably be better off writing an acceptance test language to help characterise what the desired outputs are in different situations - this gives a clear picture of what you are trying to achieve, it also allows you to throw large amounts of (real) data through a system which is probably better than a computer generated input. 您在上面提到过您正在使用数字密集型代码 - 可能值得测试上面的级别,因此您可以测试您正在寻找的系统中的行为而不仅仅是数字运算 - 假设代码不是纯数字,这将是帮助您建立一些真实的执行条件,并确保无论数字运算位数实际上正在以您需要的方式与程序的其余部分进行交互 - 如果它是某种算法,您可能最好不要编写验收测试语言有助于描述在不同情况下所需输出的特征 - 这可以清楚地显示您想要实现的内容,它还允许您通过系统丢弃大量(实际)数据,这可能比计算机生成的更好输入。 The other benefit of this is that if you realise the algorithm needs a drastic rewrite in order to meet some new requirement then all you have to do is add the new test case and then rewrite/refactor; 这样做的另一个好处是,如果你意识到算法需要大量重写以满足一些新的要求,那么你所要做的就是添加新的测试用例然后重写/重构; if your tests were just looking at the details of the algorithm and assuming the effects on the outside world then you would have a substantial headache trying to figure out how the algorithm currently influences behaviour, which parts were correct and which were not and then trying to migrate a load of unit tests onto a new API/algorithm. 如果你的测试只是查看算法的细节并假设对外界的影响,那么你会有一个实质性的头痛试图找出算法当前如何影响行为,哪些部分是正确的,哪些不是然后尝试将大量单元测试迁移到新的API /算法上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM