It would be great if they could go into more detail on what they've improved over pyhamcrest (https://github.com/hamcrest/PyHamcrest) which I do use on occasion when there is no other easy way to write a good matcher. That said though, pytest's assertion rewriting goes a long way towards making hamcrest-style assertions redundant. But not completely.
Better error messages was the motivation: PyHamcrest tends to put everything onto one line, which makes it hard to discern structure. In contrast, precisely tries to produce an error message that uses line breaks and indentation to match the structure of the matcher, hopefully making it clear exactly which part of the matcher has failed.
It's still not that easy to assert on some of the keys in a dict but not others, especially if you only want to assert on some of the keys nested inside that key, and so on. There are a few other cases that perhaps don't come to mind straight away, many to do with having complex rules for what is allowed to be in another thing.
The case is more like when you want to assert against some of the contents of a dictionary but not all (say 60% of a 30 key dict), and not all those assertions are based on == (and it's a multilevel nested dict).
There's no particurly terse why to write an example I'm afraid.
If the author of the library is reading, I think it would be a great addition to have a section discussing the benefit vs writing your own one line checkers.
One of the biggest benefits of libraries like this is that they tend to explicitly state the test author's intent.
To take your example from up top: If I'm coming to the code later, and I notice that it's not asserting for the absence of anything, it may be very difficult for me to tell whether that behavior is your intent, or just a brain fart.
It's just another layer of confusion in the many layers of confusion that lead to test rot.
Ah that's better than my collections.Counter trick. Yours only needs the items to comparible rather than hashable, which is usually a looser requirement. (In principle you could have an object that's hashable but not comparible I can't immediately think of any).
The main problem is probably heterogenous collections. If you have a collection with both ints and strings then hashing will work fine but comparing will fail (in Python 3).
(Frozensets are hashable but not sortable but that's probably more niche.)
If you were to ask me "Should I use precisely in my tests?", my answer would be: it depends. The main benefit is to better describe the intent of your test, so that the assertion is neither under- nor over-specified, with the intent directly stated.
Assuming your assertion is meant to be an alternative to the example in the README:
assert_that(result, contains_exactly("a", "b"))
I'd suggest that the above states the intention of the assertion, rather than how you check it. For instance, your assertion would allow duplicate elements, whereas the assertion as originally written would suggest that this isn't desired. As other comments have pointed out, you can do things with sorted, Counter or set (depending on exactly what you want to assert), but why worry about what trick to use when you could just directly state your intention?
The assertion using precisely is also (arguably) easier for a reader to know what is (and isn't) being asserted in the test, and makes the test less brittle since you're not accidentally asserting more than intended (for instance, it's common to assert equality with a list, even though you don't actually care about order).
Another common case is when you want to make assertions on a collection, but equality would check too much. For instance, suppose you have a function that fetches users from a database. The fetch can return the users in any order, and you just want to check the names of the returning users, so you can write something like:
Now we've over-specified our test -- we need to know irrelevant details like the ID and e-mail address of the users, which might change and break this test even when the functionality we care about still works. We'll also break the test if we add any more attributes to users.
As you've mentioned, there's a cost to learning precisely. Even if you're familiar with the library, then you're still potentially writing a more complex assertion (where more can go wrong) than just (for instance) an equality assertion. In my experience, on many projects, the ability to state the intent of assertions precisely has far outweighed the downsides, but that's from a position of already being comfortable with the library.
Unfortunately that is a misleading headline since these are not better assertions for Python tests. These appear to be an attempt to infect Python code with pointless verbosity found in AssertJ or Hamcrest for Java.
I tend to try and lean on the language as much as possible before pulling in libraries like this. This is the sort of thing that you end up regretting a year or two later when the author abandons the project and you can no longer get help for bugs. Unlike vanilla language assertions, you won't need to rewrite your entire test suite when that situation inevitably comes up.
pytest will give you really awesome feedback with vanilla/basic 'assert x in y' statements
Many years ago I wrote https://github.com/elifiner/affirm which replaces the built-in assert statement and provides similar (?) benefits without changing the syntax.