Slide 1

Slide 1 text

ුಈখ਺ͷൺֱ LJTIJLBXBLBUTVNJ !LJTIJLBXBLBUTVNJ!IBDIZEFSNJP LJTIJLBXBLBUTVNJ

Slide 2

Slide 2 text

ුಈখ਺ͷൺֱ

Slide 3

Slide 3 text

let center = CGPoint(x: 900, y: 900) let radius: CGFloat = 1000 let p = pointOnCircle(center: center, radius: radius, angle: .pi / 2) #expect(p.x == center.x)

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

let center = CGPoint(x: 900, y: 900) let radius: CGFloat = 1000 let p = pointOnCircle(center: center, radius: radius, angle: .pi / 2) XCTAssertEqual(p.x, center.x, accuracy: 0.000001)

Slide 7

Slide 7 text

XCTest Swift Testing XCTAssert(x), XCTAssertTrue(x) #expect(x) XCTAssertFalse(x) #expect(!x) XCTAssertNil(x) #expect(x == nil) XCTAssertNotNil(x) #expect(x != nil) XCTAssertEqual(x, y) #expect(x == y) XCTAssertNotEqual(x, y) #expect(x != y) XCTAssertIdentical(x, y) #expect(x === y) XCTAssertNotIdentical(x, y) #expect(x !== y) XCTAssertGreaterThan(x, y) #expect(x > y) XCTAssertGreaterThanOrEqual(x, y) #expect(x >= y) XCTAssertLessThanOrEqual(x, y) #expect(x <= y) XCTAssertLessThan(x, y) #expect(x < y) XCTAssertThrowsError(try f()) #expect(throws: (any Error).self) { try f() } XCTAssertThrowsError(try f()) { error in … } let error = #expect(throws: (any Error).self) { try f() } XCTAssertNoThrow(try f()) #expect(throws: Never.self) { try f() } try XCTUnwrap(x) try #require(x) XCTFail("…") Issue.record("…")

Slide 8

Slide 8 text

9$5FTU4XJGU5FTUJOH The testing library doesn’t provide an equivalent of XCTAssertEqual(_:_:accuracy:_:file:line:). To compare two numeric values within a speci fi ed accuracy, use isApproximatelyEqual() from swift-numerics.

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

XCTAssertEqual(p.x, center.x, accuracy: 0.000001) 9$5FTU 9$5"TTFSU&RVBM @@BDDVSBDZ@ fi MFMJOF

Slide 12

Slide 12 text

4XJGU/VNFSJDT JT"QQSPYJNBUFMZ&RVBM UPSFMBUJWF5PMFSBODFOPSN p.x.isApproximatelyEqual( to: center.x, absoluteTolerance: ???, relativeTolerance: ???, norm: ??? )

Slide 13

Slide 13 text

9$"TTFSU&RVBM *NQMFNFOUBUJPO private func areEqual(_ exp1: T, _ exp2: T, accuracy: T) -> Bool { // Test with equality first to handle comparing inf/-inf with itself. if exp1 == exp2 { return true } else { // NaN values are handled implicitly, since the <= operator returns false when comparing any value to NaN. let difference = (exp1.magnitude > exp2.magnitude) ? exp1 - exp2 : exp2 - exp1 return difference.magnitude <= accuracy.magnitude } } https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/XCTest/Public/XCTAssert.swift

Slide 14

Slide 14 text

9$"TTFSU&RVBM *NQMFNFOUBUJPO private func areEqual(_ exp1: T, _ exp2: T, accuracy: T) -> Bool { // Test with equality first to handle comparing inf/-inf with itself. if exp1 == exp2 { return true } else { // NaN values are handled implicitly, since the <= operator returns false when comparing any value to NaN. let difference = (exp1.magnitude > exp2.magnitude) ? exp1 - exp2 : exp2 - exp1 return difference.magnitude <= accuracy.magnitude } } https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/XCTest/Public/XCTAssert.swift

Slide 15

Slide 15 text

9$"TTFSU&RVBM *NQMFNFOUBUJPO private func areEqual(_ exp1: T, _ exp2: T, accuracy: T) -> Bool { // Test with equality first to handle comparing inf/-inf with itself. if exp1 == exp2 { return true } else { // NaN values are handled implicitly, since the <= operator returns false when comparing any value to NaN. let difference = (exp1.magnitude > exp2.magnitude) ? exp1 - exp2 : exp2 - exp1 return difference.magnitude <= accuracy.magnitude } } https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/XCTest/Public/XCTAssert.swift

Slide 16

Slide 16 text

9$"TTFSU&RVBM *NQMFNFOUBUJPO private func areEqual(_ exp1: T, _ exp2: T, accuracy: T) -> Bool { // Test with equality first to handle comparing inf/-inf with itself. if exp1 == exp2 { return true } else { // NaN values are handled implicitly, since the <= operator returns false when comparing any value to NaN. let difference = (exp1.magnitude > exp2.magnitude) ? exp1 - exp2 : exp2 - exp1 return difference.magnitude <= accuracy.magnitude } } https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/XCTest/Public/XCTAssert.swift

Slide 17

Slide 17 text

9$"TTFSU&RVBM abs(exp1 - exp2) <= accuracy

Slide 18

Slide 18 text

4XJGU5FTUJOH FYQFDU XCTAssertEqual(p.x, center.x, accuracy: 0.000001) #expect(abs(p.x - center.x) <= 0.000001)

Slide 19

Slide 19 text

4XJGU/VNFSJDTͷ࣮૷͸ͳͥෳࡶ͔

Slide 20

Slide 20 text

https://github.com/apple/swift-numerics/blob/main/Sources/RealModule/ApproximateEquality.swift public func isApproximatelyEqual( to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude ) -> Bool where Magnitude: FloatingPoint { assert( absoluteTolerance >= 0 && absoluteTolerance.isFinite, "absoluteTolerance should be non-negative and finite, " + "but is \(absoluteTolerance)." ) assert( relativeTolerance >= 0 && relativeTolerance <= 1, "relativeTolerance should be non-negative and <= 1, " + "but is \(relativeTolerance)." ) if self == other { return true } let delta = norm(self - other) let scale = max(norm(self), norm(other)) let bound = max(absoluteTolerance, scale*relativeTolerance) return delta.isFinite && delta <= bound }

Slide 21

Slide 21 text

r ઈରޡࠩabs(a - b) < tolerance ʢྫʣ9$5FTUͷXCTAssertEqual(_:_:accuracy:) r ઈରޡࠩ ૬ରޡࠩabs(a - b) <= max(absTol, scale * relTol) ʢྫʣTXJGUOVNFSJDT r ओʹ૬ରޡࠩɺθϩ෇ۙΛಛผѻ͍ ʢྫʣ4& ઈରޡࠩɾ૬ରޡࠩ 'MPBUJOH1PJOU$PNQBSJTPO

Slide 22

Slide 22 text

r 9$5FTUͰఏڙ͞Ε͍ͯΔؔ਺Ͱ࠾༻ r 6*ͷ࠲ඪͷܭࢉ݁ՌͳͲڐ༰ޡࠩ͸QY΍QYͱ͍͏͜ͱ͕΄ͱΜͲɺͷΑ͏ ͳ৔߹ʹ࢖͍΍͍͢ ʢྫʣϏϡʔΛ̏౳෼ͨ͠େ͖͞ʹฒ΂Δɺ ɹɹɹςΩετ͕ϐολϦऩ·Δେ͖͞ΛٻΊΔ ઈରޡࠩ ઈରޡࠩɾ૬ରޡࠩ

Slide 23

Slide 23 text

r ઈରޡࠩ͸஋ͷεέʔϧ͕มΘΔͱޡࠩͷҙຯ͕มΘͬͯ͠·͏ ʹରͯ͠ޡࠩ͸ˋͷ͕ࠩͩɺ    ʹରͯ͠͸΄΅ಉ͡஋ r ݁Ռͱͯ͠খ͞ͳ஋ͱେ͖ͳ஋ͰޡࠩΛ౷Ұతʹѻ͑ͳ͍ θϩ෇ۙͰ͸ޡ͕ࠩ؇͗͢ɺେ͖ͳ஋Ͱ͸ݫ͗͢͠Δ ઈରޡ͚ࠩͩͰ͸ࠔΔ͜ͱ ઈରޡࠩɾ૬ରޡࠩ

Slide 24

Slide 24 text

r ڐ༰ޡࠩΛׂ߹ʢൺ཰ʣͰද͢ r 4XJGU/VNFSJDTͷ৔߹͸ʙͷ஋ r θϩ΍θϩ෇ۙͷ஋ʹରͯ͠͸ڐ༰ޡ͕ࠩ΄΅θϩʹͳͬͯ͠·͏ ૬ରޡࠩ ઈରޡࠩɾ૬ରޡࠩ

Slide 25

Slide 25 text

r θϩ෇ۙͷখ͞ͳ஋͸ઈରޡࠩɺڊେͳ஋ʹରͯ͠͸૬ରޡࠩΛ࢖͏ r ͲͷΑ͏ͳ஋Ͱ΋ൺֱΛ౷Ұతͳํ๏Ͱߦ͑Δ r ୯ʹઈରޡࠩͱ૬ରޡࠩΛ྆ํࢦఆ͍ͯ͠ΔΘ͚Ͱ͸ͳ͘ɺҰͭͷࣜʹΑͬͯ ∣a−b∣ ≤ max(absTol, scale × relTol) ઈରޡࠩʢBCT5PMʣͱ૬ରޡࠩʢTDBMFºSFM5PMʣ͕౳͘͠ͳΔڥքͰࣗಈతʹ ੾ΓସΘΔ ઈରޡࠩͱ૬ରޡࠩͷ߹੒ʢ4XJGU/VNFSJDTʣ ઈରޡࠩɾ૬ରޡࠩ

Slide 26

Slide 26 text

https://github.com/apple/swift-numerics/blob/main/Sources/RealModule/ApproximateEquality.swift public func isApproximatelyEqual( to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude ) -> Bool where Magnitude: FloatingPoint { assert( absoluteTolerance >= 0 && absoluteTolerance.isFinite, "absoluteTolerance should be non-negative and finite, " + "but is \(absoluteTolerance)." ) assert( relativeTolerance >= 0 && relativeTolerance <= 1, "relativeTolerance should be non-negative and <= 1, " + "but is \(relativeTolerance)." ) if self == other { return true } let delta = norm(self - other) let scale = max(norm(self), norm(other)) let bound = max(absoluteTolerance, scale*relativeTolerance) return delta.isFinite && delta <= bound }

Slide 27

Slide 27 text

https://github.com/apple/swift-numerics/blob/main/Sources/RealModule/ApproximateEquality.swift public func isApproximatelyEqual( to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude ) -> Bool where Magnitude: FloatingPoint { assert( absoluteTolerance >= 0 && absoluteTolerance.isFinite, "absoluteTolerance should be non-negative and finite, " + "but is \(absoluteTolerance)." ) assert( relativeTolerance >= 0 && relativeTolerance <= 1, "relativeTolerance should be non-negative and <= 1, " + "but is \(relativeTolerance)." ) if self == other { return true } let delta = norm(self - other) let scale = max(norm(self), norm(other)) let bound = max(absoluteTolerance, scale*relativeTolerance) return delta.isFinite && delta <= bound }

Slide 28

Slide 28 text

https://github.com/apple/swift-numerics/blob/main/Sources/RealModule/ApproximateEquality.swift public func isApproximatelyEqual( to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude ) -> Bool where Magnitude: FloatingPoint { assert( absoluteTolerance >= 0 && absoluteTolerance.isFinite, "absoluteTolerance should be non-negative and finite, " + "but is \(absoluteTolerance)." ) assert( relativeTolerance >= 0 && relativeTolerance <= 1, "relativeTolerance should be non-negative and <= 1, " + "but is \(relativeTolerance)." ) if self == other { return true } let delta = norm(self - other) let scale = max(norm(self), norm(other)) let bound = max(absoluteTolerance, scale*relativeTolerance) return delta.isFinite && delta <= bound }

Slide 29

Slide 29 text

https://github.com/apple/swift-numerics/blob/main/Sources/RealModule/ApproximateEquality.swift public func isApproximatelyEqual( to other: Self, absoluteTolerance: Magnitude, relativeTolerance: Magnitude = 0, norm: (Self) -> Magnitude ) -> Bool where Magnitude: FloatingPoint { assert( absoluteTolerance >= 0 && absoluteTolerance.isFinite, "absoluteTolerance should be non-negative and finite, " + "but is \(absoluteTolerance)." ) assert( relativeTolerance >= 0 && relativeTolerance <= 1, "relativeTolerance should be non-negative and <= 1, " + "but is \(relativeTolerance)." ) if self == other { return true } let delta = norm(self - other) let scale = max(norm(self), norm(other)) let bound = max(absoluteTolerance, scale*relativeTolerance) return delta.isFinite && delta <= bound }

Slide 30

Slide 30 text

JT"QQSPYJNBUFMZ&RVBM abs(a - b) <= max(absTol, scale * relTol)

Slide 31

Slide 31 text

JT"QQSPYJNBUFMZ&RVBM abs(a - b) <= max(absTol, scale * relTol)

Slide 32

Slide 32 text

<1SPPGPG$PODFQU> fl PBUJOHQPJOUBDDVSBDZPQFSBUJPOT 4XJGU5FTUJOHઐ༻ͷԋࢉࢠͷఏҊ https://github.com/swiftlang/swift-testing/issues/165 #expect((p.x == center.x) ± 5.0)

Slide 33

Slide 33 text

r ුಈখ਺͸׬શҰகͷൺֱ͸Ͱ͖ͳ͍ͷͰڐ༰ޡࠩ಺ͳΒҰகͱߟ͑Δ r ڐ༰ޡࠩ͸ઈରޡࠩͱ૬ରޡ͕ࠩ͋Δ r ஋ͷੑ࣭΍খ͞ͳ஋ͱڊେͳ஋ʹΑͬͯ࢖͍෼͚Δ r 4XJGU/VNFSJDT͸แׅతͳαϙʔτΛఏڙ͍ͯ͠ΔͷͰ9$5FTUΑΓ΋೉͘͠ݟ ͑Δ r 4XJGU5FTUJOHͰ9$5FTUͱಉ౳ͳؔ਺͕ཉ͍͚ͩ͠ͳΒabs(a - b) <= tol ͱ͍͏ؔ਺Λαοͱॻ͘ͷ΋ΞϦ ·ͱΊ ුಈখ਺ͷൺֱɾͦΕͧΕͷ࣮૷ͷҧ͍

Slide 34

Slide 34 text

r %PDVNFOUUIFSFDPNNFOEFEQBUUFSOGPSQFSGPSNJOH fl PBUJOHQPJOU FRVBMJUZXJUIBDDVSBDZFYQFDUBUJPOT BOBMPHPVTUP 9$5"TTFSU&RVBM @@BDDVSBDZ  IUUQTHJUIVCDPNTXJGUMBOHTXJGUUFTUJOHJTTVFT r 9$5"TTFSU&RVBMXJUIBDDVSBDZ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOYDUFTU YDUBTTFSUFRVBM @@BDDVSBDZ@ fi MFMJOF FQV r "QQSPYJNBUF&RVBMJUZTXJGU 4XJGU/VNFSJDT  IUUQTHJUIVCDPNBQQMFTXJGUOVNFSJDTCMPCNBJO4PVSDFT3FBM.PEVMF "QQSPYJNBUF&RVBMJUZTXJGU ࢀߟจݙ