diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 0ee088a1f293c08dfd6aa708b544d4c431c0ce8e..469a36bdb3dcd073d9b3fc402a381e0aa7e28af8 100755
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -23,6 +23,9 @@ require_once $_tests_dir . '/includes/functions.php';
  * Manually load the plugin being tested.
  */
 function _manually_load_plugin() {
+	// Plugin requires pretty permalinks to function.
+	_set_default_permalink_structure_for_tests();
+
 	require dirname( dirname( __FILE__ ) ) . '/eth-redirect-to-latest.php';
 }
 tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
diff --git a/tests/test-plugin.php b/tests/test-plugin.php
new file mode 100755
index 0000000000000000000000000000000000000000..1908c72786099041fb9d2ffbc580a9f03b492c01
--- /dev/null
+++ b/tests/test-plugin.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Class PluginTest.
+ *
+ * @package ETH_Redirect_To_Latest_Post
+ */
+
+/**
+ * Plugin test case.
+ */
+class PluginTest extends WP_UnitTestCase {
+	/**
+	 * ID of latest post.
+	 *
+	 * @var int
+	 */
+	protected static $latest_id;
+
+	/**
+	 * Create some objects with various dates, so something
+	 * can be considered "latest."
+	 *
+	 * We create an assortment of posts and pages with the
+	 * slug used for redirection so that we can confirm that
+	 * redirection takes priority.
+	 */
+	public function setUp() {
+		parent::setUp();
+
+		$this->factory->post->create_many(
+			10,
+			array(
+				'post_date' => date( 'Y-m-d H:i:s', strtotime( '-1 minute' ) ),
+				'post_name' => 'latest',
+			)
+		);
+
+		$this->factory->post->create_many(
+			10,
+			array(
+				'post_date' => date( 'Y-m-d H:i:s', strtotime( '-1 hour' ) ),
+				'post_name' => 'latest',
+			)
+		);
+
+		$this->factory->post->create_many(
+			10,
+			array(
+				'post_date' => date( 'Y-m-d H:i:s', strtotime( '-1 minute' ) ),
+				'post_type' => 'page',
+				'post_name' => 'latest',
+			)
+		);
+
+		$this->factory->post->create_many(
+			10,
+			array(
+				'post_date' => date( 'Y-m-d H:i:s', strtotime( '-1 hour' ) ),
+				'post_type' => 'page',
+				'post_name' => 'latest',
+			)
+		);
+
+		static::$latest_id = $this->factory->post->create();
+	}
+
+	/**
+	 * Test function that retrieves latest post when
+	 * requested as a non-hierarchical permastruct.
+	 */
+	public function test_get_latest_non_hierarchical() {
+		$fake_request = new stdClass();
+		$fake_request->query_vars = array(
+			'name' => 'latest',
+		);
+
+		$this->assert_for_request( $fake_request );
+	}
+
+	/**
+	 * Test function that retrieves latest post when
+	 * requested as a non-hierarchical permastruct.
+	 */
+	public function test_get_latest_hierarchical() {
+		$fake_request = new stdClass();
+		$fake_request->query_vars = array(
+			'pagename' => 'latest',
+		);
+
+		$this->assert_for_request( $fake_request );
+	}
+
+	/**
+	 * Helper for shared assertions.
+	 *
+	 * @param stdClass $fake_request Faux WP object.
+	 */
+	protected function assert_for_request( $fake_request ) {
+		$redirect = ETH_Redirect_To_Latest_Post::get_instance()->get_redirect_for_request( $fake_request );
+
+		$this->assertEquals(
+			get_permalink( static::$latest_id ),
+			$redirect->destination,
+			'Failed to assert that redirect destination is permalink of latest post.'
+		);
+
+		$this->assertEquals(
+			302,
+			$redirect->status_code,
+			'Failed to assert that redirect status code is for a temporary redirect.'
+		);
+	}
+
+	/**
+	 * Test that redirection doesn't return a post with
+	 * the slug that's also used for redirection.
+	 */
+	public function test_not_matching_post_name() {
+		$fake_request = new stdClass();
+		$fake_request->query_vars = array(
+			'name' => 'latest',
+		);
+
+		$redirect = ETH_Redirect_To_Latest_Post::get_instance()->get_redirect_for_request( $fake_request );
+
+		$object_by_slug = get_posts(
+			[
+				'posts_per_page' => 1,
+				'post_status'    => 'any',
+				'name'           => $fake_request->query_vars['name'],
+			]
+		);
+
+		$this->assertCount(
+			1,
+			$object_by_slug,
+			'Failed to assert that a post exists with the slug used for redirection.'
+		);
+
+		$object_by_slug = array_shift( $object_by_slug );
+
+		$this->assertNotEquals(
+			get_permalink( $object_by_slug ),
+			$redirect->destination,
+			'Failed to assert that latest post is not the object with the slug "latest."'
+		);
+	}
+
+	/**
+	 * Test that redirection doesn't return a post with
+	 * the slug that's also used for redirection.
+	 */
+	public function test_not_matching_page_name() {
+		$fake_request = new stdClass();
+		$fake_request->query_vars = array(
+			'pagename' => 'latest',
+		);
+
+		$redirect = ETH_Redirect_To_Latest_Post::get_instance()->get_redirect_for_request( $fake_request );
+
+		$object_by_slug = get_posts(
+			[
+				'posts_per_page' => 1,
+				'post_status'    => 'any',
+				'post_type'      => 'page',
+				'pagename'       => $fake_request->query_vars['pagename'],
+			]
+		);
+
+		$this->assertCount(
+			1,
+			$object_by_slug,
+			'Failed to assert that a page exists with the slug used for redirection.'
+		);
+
+		$object_by_slug = array_shift( $object_by_slug );
+
+		$this->assertNotEquals(
+			get_permalink( $object_by_slug ),
+			$redirect->destination,
+			'Failed to assert that latest post is not the object with the slug "latest."'
+		);
+	}
+}
diff --git a/tests/test-sample.php b/tests/test-sample.php
deleted file mode 100755
index 605cfe1edcc9d1e8898359f71ae9e42310cb64a3..0000000000000000000000000000000000000000
--- a/tests/test-sample.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-/**
- * Class SampleTest
- *
- * @package ETH_Redirect_To_Latest
- */
-
-/**
- * Sample test case.
- */
-class SampleTest extends WP_UnitTestCase {
-
-	/**
-	 * A single example test.
-	 */
-	public function test_sample() {
-		// Replace this with some actual testing code.
-		$this->assertTrue( true );
-	}
-}