2015-05-22 22 views
2

在測試過程中,我們希望限定unicode字符,有時候有寬範圍,有時更窄。我創建了幾個特定的​​發電機:在ScalaCheck中創建unicode和unicode,但沒有空白生成器

// Generate a wide varying of Unicode strings with all legal characters (21-40 characters): 
val latinUnicodeCharacter = Gen.choose('\u0041', '\u01B5').filter(Character.isDefined) 

// Generate latin Unicode strings with all legal characters (21-40 characters): 
val latinUnicodeGenerator: Gen[String] = Gen.chooseNum(21, 40).flatMap { n => 
    Gen.sequence[String, Char](List.fill(n)(latinUnicodeCharacter)) 
} 

// Generate latin unicode strings without whitespace (21-40 characters): !! COMES UP SHORT... 
val latinUnicodeGeneratorNoWhitespace: Gen[String] = Gen.chooseNum(21, 40).flatMap { n => 
    Gen.sequence[String, Char](List.fill(n)(latinUnicodeCharacter)).map(_.replaceAll("[\\p{Z}\\p{C}]", "")) 
} 

latinUnicodeCharacter發生器從字符從標準的拉丁(「A」,「B」等)到高階拉丁字符(德國/北歐和其他人挑選)。這對測試名稱的基於拉丁的字符輸入非常有用。

latinUnicodeGenerator創建長度爲21-40個字符的字符串。這些字符串包括水平空間(不只是空格字符,還有其他「水平空間」)。

最後一個例子latinUnicodeGeneratorNoWhitespace用於說電子郵件地址。我們想要拉丁字符,但我們不需要空格,控制代碼等。 問題:因爲我正在映射最終結果String並篩選出控制字符,所以String會縮小,結果總長度小於21個字符(有時)。

所以問題是:我如何實現latinUnicodeGeneratorNoWhitespace,但在發生器內部這樣做,我總是會得到21-40個字符的字符串?

回答

1

您可以通過放在一起你的非空白字符的序列,另一個空白的,然後從任一隻有非空白採摘,或兩者同時做到這一點:

import org.scalacheck.Gen 

val myChars = ('A' to 'Z') ++ ('a' to 'z') 
val ws = Seq(' ', '\t') 

val myCharsGenNoWhitespace: Gen[String] = Gen.chooseNum(21, 40).flatMap { n => 
    Gen.buildableOfN[String, Char](n, Gen.oneOf(myChars)) 
} 

val myCharsGen: Gen[String] = Gen.chooseNum(21, 40).flatMap { n => 
    Gen.buildableOfN[String, Char](n, Gen.oneOf(myChars ++ ws)) 
} 

我會建議考慮你真正測試的是什麼 - 儘管你越限制測試用例,你就越少地檢查你的程序如何處理意外輸入。

+0

謝謝,這是一個很好的方法,我可以擴展。要回答你的問題:我們正在測試電子郵件地址處理,並且電子郵件的標準不需要空格。所以,基本上,我們需要Unicode,但沒有任何「水平空間」控制字符(這將被任何郵件服務器禁止)。 – Zac

+1

@Zac很高興幫助!如果某人已經爲有效的電子郵件地址建立了「Gen」,我不會感到驚訝,這可能值得一看。 –