Unit testing 为project Euler进行单元测试

Unit testing 为project Euler进行单元测试,unit-testing,Unit Testing,我开始讨论ProjectEuler中的问题,我想用TDD风格来解决,但是我很难找到不包含代码的问题的数字答案。有没有关于这些数据的资源,以便我可以制作测试用例来告诉我是否正确地解决了问题 我这样做的动机是,我觉得算法是答案,而不是数字。如果我看其他人的代码示例,它会破坏解决问题的挑战 编辑:我专门寻找答案的编号,没有上下文或算法,所以我可以做如下的事情。我知道它更详细,但我希望能够有一个通过/失败的结果来告诉我我的算法是否正确,而不是看别人的代码示例来知道我是否正确地完成了它 import un

我开始讨论ProjectEuler中的问题,我想用TDD风格来解决,但是我很难找到不包含代码的问题的数字答案。有没有关于这些数据的资源,以便我可以制作测试用例来告诉我是否正确地解决了问题

我这样做的动机是,我觉得算法是答案,而不是数字。如果我看其他人的代码示例,它会破坏解决问题的挑战

编辑:我专门寻找答案的编号,没有上下文或算法,所以我可以做如下的事情。我知道它更详细,但我希望能够有一个通过/失败的结果来告诉我我的算法是否正确,而不是看别人的代码示例来知道我是否正确地完成了它

import unittest
class ProblemOneTest(unittest.TestCase):
    def test_me(self):
        self.assertEquals(solve_problem_one(),233168)

if __name__ == '__main__':
    print "Problem 1 possible answer: %d" % solve_problem_one()
    sys.exit(unittest.main())

TDD和ProjectEuler分配不一定配合得很好。首先,TDD不会帮助您解决任何项目(PE)问题。这让我想起了一个著名的尝试,一个家伙试图用计算机“解数独”

TDD不是一种设计技术。在适用的情况下,它可能非常有用,但不要认为它是一颗灵丹妙药。


PE问题通常涉及到一些繁重的计算,结果是一个数字,这就是答案。为了谨慎地应用TDD,我建议您将其用于数学实用程序,作为您解决PE问题努力的一部分。例如,my utils module For PE包含用于计算素数、将数字拆分为数字、检查回文等的函数。此模块有一组测试,因为这些功能足够通用,可以进行测试。PE解决方案本身没有测试——他们唯一需要的真正测试是最终生成正确答案。

单元测试就是答案


这些问题通常很简单(不是难度,但至少是代码布局),将它们分解成各种方法/类通常是愚蠢的。

project Euler网站上的问题页面有一个输入来检查您的答案。这就是我真正需要的。

尽管这些问题在没有答案的情况下更具挑战性,但快速的谷歌搜索产生了:


是的,您可以根据单元测试提供的测试数据设置单元测试

看起来您正在使用Python来解决这些问题(我也是)。我验证不同组件的方法是对示例数据执行简单的“”语句。它运行良好,并且时间开销较少。此外,当您只需要知道问题30的新更改是否正确时,不需要运行整个测试套件


我知道我晚了3年才参加聚会,但我想我会分享一下我是如何通过TDD接近欧拉计划的

如果这对你很重要的话,我在用Python

我所做的是:

  • 每个问题(至少)都有自己的函数作为入口/出口点,不管它感觉多么琐碎或愚蠢。如果问题需要您认为将来可能需要的某种功能,那么问题也可能获得帮助函数
  • 大多数Project Euler问题在测试中都包含一个较小的演示/测试问题。这个测试问题说明了您最擅长解决的问题,但规模较小
  • 计划使用一个参数设置您的进入/退出功能,该参数允许该功能解决问题的玩具版本以及更难的全尺寸版本。例如,在我的(可笑的命名)入口点上,是get_triangle_num_,带有一个或多个除数(n)
  • 现在我还没有实现这个函数,只是命名了它。现在我将为这个问题编写两个测试:test_示例和test_问题。我现在用
    @unittest.skip('Unimplemented')
    来修饰测试问题,因为我们不知道答案。您的测试文件可能与我的类似:

    import unittest
    
    from problems.p0014 import get_triangle_num_with_n_or_more_divisors
    
    class TestHighlyDivisibleTriangleNumber(unittest.TestCase):
        def test_example(self):
            self.assertEquals(get_triangle_num_with_n_or_more_divisors(1),
                              1)
            self.assertEquals(get_triangle_num_with_n_or_more_divisors(2),
                              3)
            self.assertEquals(get_triangle_num_with_n_or_more_divisors(6),
                              28)
    
        @unittest.skip('Unimplemented')
        def test_problem(self):
            self.assertEquals(get_triangle_num_with_n_or_more_divisors(500),
                              'TODO: Replace this with answer')
    
现在您正在执行项目Euler,TDD样式。您正在使用给出的示例案例来测试您的实现代码。实际上,唯一的诀窍是以一种足够灵活的方式编写您的实现,它可以用于解决实践版本和实际版本


然后我坐下来,用n或更多的除数写出get_triangle_num。一旦通过测试,我会尝试解决真正的问题;如果成功了,我会用真实答案更新我的测试问题案例,然后bam您就有一个完整的回归测试要启动了。

我想分享一下我的方法:

Hackerrank采用TDD范式,它有一个。它使用未知测试用例为您的算法打分。它们提供了一个示例测试用例来帮助您开始。我离线开发并编写一些其他测试用例来验证我的解决方案,以获得更快、更精确的反馈

这些箱子从哪里来?您可以手工完成这些任务,也可以从本地运行的暴力强制代码生成这些任务。这样做的美妙之处在于,您必须自己考虑边缘案例,这在现实生活中更为典型

JavaScript中的测试示例:

var cases = [
  {input: '1\n15', output: '45'},
  ...
];

describe('Multiples of 3 and 5', function() {
  cases.forEach((v, i) => {
    it('test case #' + i, function () {
      assert.equal(unit(v.input), v.output);
    })
  });
});

虽然Hackerrank使用stdin和stdout,但我仍然尝试将主代码分离到函数中,并使用函数编程。

对不起,我应该说得更清楚一些。我正在寻找没有上下文的数字,这样我就可以做一些类似于
assertEquals(我的\u解决方案(),预期的\u答案)
。我将更新问题+1,只有在你已经有了答案并且你想优化它的情况下,为Project Euler问题编写测试才有意义。你可以用一个较小的极限来测试解决问题的算法,并用蛮力(我经常这样做)得出一个值。我想这太过分了,但它的动机也是想学习如何在python中使用单元测试。我也希望能够用智慧检查我的工作