TST Replace unittest.TestCase.fail calls, use pytest.raises instead of legacy constructs
Similarly to https://github.com/numpy/numpy/pull/11933,
> Following pytest migration there are unit tests that used to call unittest.TestCase.fail and now will produce a misleading error message on failure because the fail method no longer exists (test classes just inherit from object).
> 
> This fixes this issue, by raising an exception on failure explicitly.

In addition this uses `pytest.raises` instead of more complicated legacy constructions of the form,
```py
try:
   something
except ExceptedException:
   pass
else:
   raise AssertionError(error_message)
```
A few additional minor issues are discussed in comments below.