diff --git a/RoboFile.php b/RoboFile.php
index 65d03637..1e2c66a8 100644
--- a/RoboFile.php
+++ b/RoboFile.php
@@ -50,6 +50,21 @@ class RoboFile extends \Robo\Tasks {
      * recommended if debugging facilities are not otherwise needed.
     */
     public function coverage(array $args): Result {
+        // run tests with code coverage reporting enabled
+        $exec = $this->findCoverageEngine();
+        return $this->runTests($exec, "coverage", array_merge(["--coverage-html", self::BASE_TEST."coverage"], $args));
+    }
+
+    /** Produces a code coverage report, with redundant tests
+     *
+     * Depending on the environment, some tests that normally provide
+     * coverage may be skipped, while working alternatives are normally
+     * suppressed for reasons of time. This coverage report will try to
+     * run all tests which may cover code.
+     * 
+     * See also help for the "coverage" task for more details.
+    */
+    public function coverageFull(array $args): Result {
         // run tests with code coverage reporting enabled
         $exec = $this->findCoverageEngine();
         return $this->runTests($exec, "typical", array_merge(["--coverage-html", self::BASE_TEST."coverage"], $args));
@@ -88,6 +103,9 @@ class RoboFile extends \Robo\Tasks {
             case "quick":
                 $set = ["--exclude-group", "optional,slow"];
                 break;
+            case "coverage":
+                $set = ["--exclude-group", "optional,excludeFromCoverage"];
+                break;
             case "full":
                 $set = [];
                 break;
diff --git a/tests/cases/Database/SeriesArticle.php b/tests/cases/Database/SeriesArticle.php
index 74285f5f..96fd4224 100644
--- a/tests/cases/Database/SeriesArticle.php
+++ b/tests/cases/Database/SeriesArticle.php
@@ -772,6 +772,12 @@ trait SeriesArticle {
         $this->compareExpectations($state);
     }
 
+    public function testMarkMultipleMissingEditions() {
+        $this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501])));
+        $state = $this->primeExpectations($this->data, $this->checkTables);
+        $this->compareExpectations($state);
+    }
+
     public function testMarkMultipleEditionsUnread() {
         Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,1001]));
         $now = Date::transform(time(), "sql");
diff --git a/tests/cases/Db/PostgreSQL/TestDatabase.php b/tests/cases/Db/PostgreSQL/TestDatabase.php
index 91e326f4..a8b2a65a 100644
--- a/tests/cases/Db/PostgreSQL/TestDatabase.php
+++ b/tests/cases/Db/PostgreSQL/TestDatabase.php
@@ -7,6 +7,7 @@ declare(strict_types=1);
 namespace JKingWeb\Arsse\TestCase\Db\PosgreSQL;
 
 /** 
+ * @group excludeFromCoverage
  * @covers \JKingWeb\Arsse\Database<extended>
  * @covers \JKingWeb\Arsse\Misc\Query<extended>
  */