简体   繁体   中英

How to assert or validate 2 pieces of text that are “almost” identical for unit test

I'd like to validate an expected response against an actual from an actual API response as part of my unit tests.

So I have this:

Expectation:

disqualified because taxpayer can be claimed as dependent

I'd like to assert against this:

Actual:

disqualified because you can be claimed as a dependent

API response from a compiled binary.

Since these pieces of text are close enough, I'd like to pass this assertion I have in my test:

Assert.assertEquals(titleText.toLowerCase(), t.toLowerCase(), "Did not match!");

Since this assertion obviously did not pass because the 2 pieces of text are not equal.

I tried this instead:

Assert.assertTrue(titleText.toLowerCase().contains(t.toLowerCase()));

But the test still fails....How can I make this test pass? Any suggestions would be much appreciated.

You will have to write comparator of your own.

class OwnComparator {
    public static boolean checkThoseForEquality(String str1, String str2) {
        // your logic goes here
    }
}

Use it with

 assertTrue(OwnComparator.checkThoseForEquality(titleText, t);

You can even move toLowerCase() from code to this comparator, making your general code shorter.

I don't think expecting testNG to have implemented exactly what you mean by "almost equal" is valid.

The best approach would probably be to assert those parts that are predictable, using for example regex:

Assert.assertTrue(titleText
  .matches("(?i)disqualified because \\w+ can be claimed as dependent"));

The regex term \\w+ means "a series of 1 or more word characters".

Note also how regex also lets you match case insensitively via the (?i) ignore-case flag, so avoiding the toLowerCase() call.

Or

If "close enough" really is good enough, use a Levenshtein distance test, an implementation of which you can find in Apache common-lang's StringUtils.getLevenshteinDistance() method:

Assert.assertTrue(StringUtils.getLevenshteinDistance(titleText, t) < 10);

Well, if you are sure this fits you, you could use Levenshtein Distance (or some other string matching score to compare the strings.

//Checks that at most 20% of the string are different using Levenshtein distance score
assertTrue(StringUtils.getLevenshteinDistance(titleText.toLowerCase(), t.toLowerCase()) < titleText.length()*0.2)

don't use regex. regex can help you only if you know the text patterns in advance and if the patterns are relatively simple.

you have to choose a metric of similarity that best fits your needs. the most famous is Levenshtein distance (or edit distance). you can find it, for example, in apache commons . if you need something more complex, you can use fuzzy string search or even use full text search (lucene etc)

but probably you won't find any of those in assertions/matchers libraries - use dedicated tool to do the comparision

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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