【问题标题】:Clojure tests fails for identical expected and actual valuesClojure 测试对于相同的预期值和实际值失败
【发布时间】:2022-01-23 09:29:19
【问题描述】:

我正在做一个 Clojure 练习,基本上模拟汽车组装工厂。以下代码是我的“生产”代码。

(ns cars-assemble)

(def success-rate-frequencies [
  { :id 1 :interval #(= % 0), :rate 0 }
  { :id 2 :interval #(and (> % 0) (<= % 4)), :rate (/ 100 100) }
  { :id 3 :interval #(and (>= % 5) (<= % 8)), :rate (/ 90 100) }
  { :id 4 :interval #(= % 9), :rate (/ 80 100) }
  { :id 5 :interval #(>= % 10), :rate (/ 77 100) }
])

(defn get-rate-by-speed-interval [speed]
  (let [result (first (filter #((get % :interval) speed) success-rate-frequencies))]
    (get result :rate)))

(defn production-rate
  "Returns the assembly line's production rate per hour,
   taking into account its success rate"
  [speed]
  (float (* speed (* 221 (get-rate-by-speed-interval speed)))))

(defn working-items
  "Calculates how many working cars are produced per minute"
  [speed]
  (let [production-rate (production-rate speed)]
    (if (= speed 0) 0 (int (/ production-rate 60)))))

我的问题是,由于某种原因,当我运行测试时,生产代码返回正确的值,但测试仍然失败。下面我有我的测试示例。

(deftest production-rate-speed-10-test
(testing "Production rate for speed 10"
  (is (= 1701.7 (cars-assemble/production-rate 10)))))

这是我的命令lean test的输出:

FAIL in (production-rate-speed-10-test) (cars_assemble_test.clj:27)
Production rate for speed 10
expected: (= 1701.7 (cars-assemble/production-rate 10))
  actual: (not (= 1701.7 1701.7))

我试图检查它是否有任何隐藏字符,但没有找到任何东西。

我尝试过的另一件事是手动修改测试文件,将预期值转换为float(如下例所示)。但我不应该更改我的测试文件。

(is (= (float 1701.7) (cars-assemble/production-rate 10)))

【问题讨论】:

    标签: unit-testing types clojure type-conversion double


    【解决方案1】:

    = 函数检查参数是否具有相同的浮点值类型,因此当您实例化十进制数时,例如:

    (def my-decimal-number 12.000)
    

    您实际上是在实例化java.lang.Double。当您将其与 production-rate 函数返回的值进行比较时,您将收到一个错误,因为类型不同。只是更新函数production-rate 以返回double

    (defn production-rate
      "Returns the assembly line's production rate per hour,
       taking into account its success rate"
      [speed]
      (double (* speed (* 221 (get-rate-by-speed-interval speed)))))
    

    【讨论】:

    • 这行得通,但最好使用==。这个函数很少使用,但它正是用于这个用例:比较数字而不管它们的类型。最好记住浮点数学很少是完全正确的,因此您应该与一些 epsilon 进行比较,例如,(&lt; 0.0001 (abs (- x y))) 是比较浮点数的更安全的方法。
    • 这是一个很好的提示,谢谢。但是,就像我在“我不应该更改我的测试文件”问题中所说的那样。我正在使用编程练习平台来学习Clojure,测试文件只是一种在本地检查我的代码提交到Exercism平台时是否会被接受的一种方式。
    • 对于一般情况,您可能还对rel=函数感兴趣:github.com/cloojure/tupelo#floating-point-number-comparison
    • @YagoAzedias 你可以加倍努力,向他们发送公关修复their bad test
    猜你喜欢
    • 2012-08-17
    • 2013-09-07
    • 1970-01-01
    • 2020-10-09
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    相关资源
    最近更新 更多