diff --git a/qt/python/CMakeLists.txt b/qt/python/CMakeLists.txt
index cb0356b77e198aeb0870f81f4249e9fdd6e1a0f9..164ec02076e2ef22174b3d9e3945c34deb25525d 100644
--- a/qt/python/CMakeLists.txt
+++ b/qt/python/CMakeLists.txt
@@ -86,6 +86,7 @@ endif ()
     mantidqt/widgets/test/test_messagedisplay.py
     mantidqt/widgets/test/test_plotselector_model.py
     mantidqt/widgets/test/test_plotselector_presenter.py
+    mantidqt/widgets/test/test_plotselector_widget.py
   )
 
   # Tests
diff --git a/qt/python/mantidqt/utils/qt/testing/__init__.py b/qt/python/mantidqt/utils/qt/testing/__init__.py
index 7aee12dd5186f33a0a0b11f28f2051f84a7ee57a..0a2102305dc504a2eaec9e2a14e958d3c2fcd9cb 100644
--- a/qt/python/mantidqt/utils/qt/testing/__init__.py
+++ b/qt/python/mantidqt/utils/qt/testing/__init__.py
@@ -53,7 +53,7 @@ def requires_qapp(cls):
     """
     def is_test_method(name, x):
         # Python 3 returns a functions type for methods not bound to an instance
-        return name.startswith('test') and (isfunction(x) or ismethod(x))
+        return (name.startswith('test') or name == 'setUp') and (isfunction(x) or ismethod(x))
 
     for name in dir(cls):
         attr = getattr(cls, name)
diff --git a/qt/python/mantidqt/widgets/plotselector/widget.py b/qt/python/mantidqt/widgets/plotselector/widget.py
index 920f4e7a008a7666dbbb71977f7f5593d9a00f7f..e1ad8744e95fafd3fa8eac8203435ca4366614f5 100644
--- a/qt/python/mantidqt/widgets/plotselector/widget.py
+++ b/qt/python/mantidqt/widgets/plotselector/widget.py
@@ -36,7 +36,7 @@ class PlotSelectorWidget(QWidget):
 
         self.close_button = QPushButton('Close')
         self.filter_box = self._make_filter_box()
-        self.list_view, self.plot_list = self._make_plot_list()
+        self.list_view = self._make_plot_list()
 
         buttons_layout = QHBoxLayout()
         buttons_layout.addWidget(self.close_button)
@@ -66,7 +66,7 @@ class PlotSelectorWidget(QWidget):
         """
         text_box = QLineEdit(self)
         text_box.setPlaceholderText("Filter Plots")
-        text_box.setClearButtonEnabled(True)
+        #text_box.setClearButtonEnabled(True)
         return text_box
 
     def _make_plot_list(self):
@@ -78,7 +78,18 @@ class PlotSelectorWidget(QWidget):
         list_view.setSelectionMode(QAbstractItemView.ExtendedSelection)
         plot_list = QStandardItemModel(list_view)
         list_view.setModel(plot_list)
-        return list_view, plot_list
+        return list_view
+
+    def set_plot_list(self, plot_list):
+        """
+        Populate the plot list from the Presenter
+        :param plot_list: the list of plot names (list of strings)
+        """
+        self.list_view.model().clear()
+        for plot_name in plot_list:
+            item = QStandardItem(plot_name)
+            item.setEditable(False)
+            self.list_view.model().appendRow(item)
 
     def get_all_selected_plot_names(self):
         selected = self.list_view.selectedIndexes()
@@ -91,16 +102,5 @@ class PlotSelectorWidget(QWidget):
         index = self.list_view.currentIndex()
         return index.data(Qt.DisplayRole)
 
-    def set_plot_list(self, plot_list):
-        """
-        Populate the plot list from the Presenter
-        :param plot_list: the list of plot names (list of strings)
-        """
-        self.plot_list.clear()
-        for plot_name in plot_list:
-            item = QStandardItem(plot_name)
-            item.setEditable(False)
-            self.plot_list.appendRow(item)
-
     def get_filter_text(self):
         return self.filter_box.text()
diff --git a/qt/python/mantidqt/widgets/test/test_plotselector_widget.py b/qt/python/mantidqt/widgets/test/test_plotselector_widget.py
new file mode 100644
index 0000000000000000000000000000000000000000..f77b7fe432912b3c54308d3b0a050ee541600f67
--- /dev/null
+++ b/qt/python/mantidqt/widgets/test/test_plotselector_widget.py
@@ -0,0 +1,126 @@
+#  This file is part of the mantid workbench.
+#
+#  Copyright (C) 2018 mantidproject
+#
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import absolute_import, division, print_function
+
+from qtpy.QtCore import Qt
+from qtpy.QtTest import QTest
+
+from mantidqt.utils.qt.testing import requires_qapp
+
+from mantidqt.widgets.plotselector.presenter import PlotSelectorPresenter
+from mantidqt.widgets.plotselector.widget import PlotSelectorWidget
+
+import unittest
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+
+
+@requires_qapp
+class PlotSelectorWidgetTest(unittest.TestCase):
+
+    def setUp(self):
+        self.presenter = mock.Mock(spec=PlotSelectorPresenter)
+        self.widget = PlotSelectorWidget(self.presenter)
+
+    def test_setting_plot_names_sets_names_in_list_view(self):
+        plot_names = ["Plot1", "Plot2", "Plot3"]
+        self.widget.set_plot_list(plot_names)
+
+        list_model = self.widget.list_view.model()
+        for index in range(list_model.rowCount()):
+            item = list_model.item(index)
+            self.assertEqual(item.data(Qt.DisplayRole), plot_names[index])
+
+    def test_setting_plot_names_to_empty_list(self):
+        plot_names = []
+        self.widget.set_plot_list(plot_names)
+
+        list_model = self.widget.list_view.model()
+        self.assertEqual(list_model.rowCount(), 0)
+
+    def test_getting_all_selected_plot_names(self):
+        plot_names = ["Plot1", "Plot2", "Plot3"]
+        self.widget.set_plot_list(plot_names)
+
+        self.widget.list_view.selectAll()
+        selected_plots = self.widget.get_all_selected_plot_names()
+        self.assertEqual(selected_plots, plot_names)
+
+    def test_getting_all_selected_plot_names_with_nothing_selected_returns_empty_list(self):
+        selected_plots = self.widget.get_all_selected_plot_names()
+        self.assertEqual(selected_plots, [])
+
+    def test_getting_currently_selected_plot_name(self):
+        plot_names = ["Plot1", "Plot2", "Plot3"]
+        self.widget.set_plot_list(plot_names)
+
+        # It would be nice to avoid this, but could not find a way to
+        # get the list item as a QWidget
+        model_index = self.widget.list_view.model().index(1, 0)
+        item_center = self.widget.list_view.visualRect(model_index).center()
+        QTest.mouseClick(self.widget.list_view.viewport(), Qt.LeftButton, pos=item_center)
+
+        selected_plot = self.widget.get_currently_selected_plot_name()
+        self.assertEquals(selected_plot, plot_names[1])
+
+    def test_getting_currently_selected_plot_name_with_nothing_selected_returns_None(self):
+        plot_names = ["Plot1", "Plot2", "Plot3"]
+        self.widget.set_plot_list(plot_names)
+
+        selected_plot = self.widget.get_currently_selected_plot_name()
+        self.assertEquals(selected_plot, None)
+
+    # ------------------------ Plot Closing -------------------------
+
+    def test_close_button_pressed_calls_presenter(self):
+        QTest.mouseClick(self.widget.close_button, Qt.LeftButton)
+        self.assertEquals(self.presenter.close_button_clicked.call_count, 1)
+        QTest.mouseClick(self.widget.close_button, Qt.LeftButton)
+        self.assertEquals(self.presenter.close_button_clicked.call_count, 2)
+
+    # ----------------------- Plot Filtering ------------------------
+
+    def test_filter_text_typing_calls_presenter_and_sets_filter_text(self):
+        QTest.keyClicks(self.widget.filter_box, 'plot1')
+        self.assertEquals(self.presenter.filter_text_changed.call_count, 5)
+        self.assertEquals(self.widget.get_filter_text(), 'plot1')
+
+    def test_programtic_filter_box_change_calls_presenter_and_sets_filter_text(self):
+        self.widget.filter_box.setText('plot1')
+        self.assertEquals(self.presenter.filter_text_changed.call_count, 1)
+        self.assertEquals(self.widget.get_filter_text(), 'plot1')
+
+    # ----------------------- Plot Selection ------------------------
+
+    def test_plot_name_double_clicked_calls_presenter_and_makes_plot_current(self):
+        plot_names = ["Plot1", "Plot2", "Plot3"]
+        self.widget.set_plot_list(plot_names)
+
+        model_index = self.widget.list_view.model().index(1, 0)
+        item_center = self.widget.list_view.visualRect(model_index).center()
+        # This single click should not be required, but otherwise the double click is not registered
+        QTest.mouseClick(self.widget.list_view.viewport(), Qt.LeftButton, pos=item_center)
+        QTest.mouseDClick(self.widget.list_view.viewport(), Qt.LeftButton, pos=item_center)
+
+        self.assertEqual(self.presenter.list_double_clicked.call_count, 1)
+        self.assertEqual(self.widget.get_currently_selected_plot_name(), plot_names[1])
+
+
+if __name__ == '__main__':
+    unittest.main()