Covergroups are useful when you are running a randomized set of regression tests. In these tests, you have seferal variables that take on a different value each time the test is run. For example, you may have a complicated block that has a lot of configuration registers that control that block's behaviour in simulation, so you randomize the contents written to the configuration registers every run and that test ensures that the block behaves as expected. Assertions are one of the tools that ensure this.
In the testbench the values you write into the config registers will be randomized on each test. You want to make sure that your randomized regression covers all of the values of these registers. So you assign covergroups to these configuration values. At the end of the regression run, if any covergroup shows 0 hits, you know your regression suite never tested those values. Therefore you will have to do something before the next regression run (i.e. add a test, modify a current test, or do more runs of some tests) in order to make sure those values are covered.
r.b.