Django unit testing: Separating unit tests without querying the database multiple times












1















I have a pair of tests like this:



Make sure a task's deletion status initializes as None



def test_initial_task_deletion_status_is_none(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
self.assertIsNone(unfinished_task.delete_status)

# Make sure a task's deletion status changes appropriately
def test_unfinished_task_deletion_status_updates_appropriately(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
unfinished_task.timed_delete(delta=.1)
self.assertIs(unfinished_task.delete_status, "Marked for Deletion")


This will go on, but I'll have unfinished_task = Task.objects.get(tasked_with="Unfinished Test") at the beginning of every one. Is there a way to split these types of things into separate tests, but use the same query result?










share|improve this question























  • No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

    – Daniel Roseman
    Jan 17 at 19:15
















1















I have a pair of tests like this:



Make sure a task's deletion status initializes as None



def test_initial_task_deletion_status_is_none(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
self.assertIsNone(unfinished_task.delete_status)

# Make sure a task's deletion status changes appropriately
def test_unfinished_task_deletion_status_updates_appropriately(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
unfinished_task.timed_delete(delta=.1)
self.assertIs(unfinished_task.delete_status, "Marked for Deletion")


This will go on, but I'll have unfinished_task = Task.objects.get(tasked_with="Unfinished Test") at the beginning of every one. Is there a way to split these types of things into separate tests, but use the same query result?










share|improve this question























  • No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

    – Daniel Roseman
    Jan 17 at 19:15














1












1








1








I have a pair of tests like this:



Make sure a task's deletion status initializes as None



def test_initial_task_deletion_status_is_none(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
self.assertIsNone(unfinished_task.delete_status)

# Make sure a task's deletion status changes appropriately
def test_unfinished_task_deletion_status_updates_appropriately(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
unfinished_task.timed_delete(delta=.1)
self.assertIs(unfinished_task.delete_status, "Marked for Deletion")


This will go on, but I'll have unfinished_task = Task.objects.get(tasked_with="Unfinished Test") at the beginning of every one. Is there a way to split these types of things into separate tests, but use the same query result?










share|improve this question














I have a pair of tests like this:



Make sure a task's deletion status initializes as None



def test_initial_task_deletion_status_is_none(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
self.assertIsNone(unfinished_task.delete_status)

# Make sure a task's deletion status changes appropriately
def test_unfinished_task_deletion_status_updates_appropriately(self):
unfinished_task = Task.objects.get(tasked_with="Unfinished Test")
unfinished_task.timed_delete(delta=.1)
self.assertIs(unfinished_task.delete_status, "Marked for Deletion")


This will go on, but I'll have unfinished_task = Task.objects.get(tasked_with="Unfinished Test") at the beginning of every one. Is there a way to split these types of things into separate tests, but use the same query result?







django unit-testing






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 17 at 18:54









AmagicalFishyAmagicalFishy

380113




380113













  • No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

    – Daniel Roseman
    Jan 17 at 19:15



















  • No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

    – Daniel Roseman
    Jan 17 at 19:15

















No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

– Daniel Roseman
Jan 17 at 19:15





No you can't, because the database is destroyed and recreated for each test anyway. You can put the query into setUp and assign the result to an instance variable, but it'll still be executed each time.

– Daniel Roseman
Jan 17 at 19:15












2 Answers
2






active

oldest

votes


















1














Assuming you're using Django's testing framework, then you can do this using setUp().
More about unittest.TestCase.setUp() here



So your updated snippet would look like:



from django.test import TestCase

class MyTestCase(TestCase):
def setUp(self):
self.unfinished_task = Task.objects.get(tasked_with="Unfinished Test")

def test_initial_task_deletion_status_is_none(self):
self.assertIsNone(self.unfinished_task.delete_status)

# Make sure a task's deletion status changes appropriately
def test_unfinished_task_deletion_status_updates_appropriately(self):
self.unfinished_task.timed_delete(delta=.1)
self.assertIs(self.unfinished_task.delete_status, "Marked for Deletion")





share|improve this answer































    1














    You can place the repeated line in the setUp method, and that will make your code less repetitive, but as DanielRoseman pointed out, it will still be run for each test, so you won't be using the same query result.



    You can place it in the setUpTestData method, and it will be run only once, before all the tests in MyTestCase, but then your unfinished_task object will be a class variable, shared across all the tests. In-memory modifications made to the object during one test will carry over into subsequent tests, and that is not what you want.



    In read-only tests, using setUpTestData is a good way to cut out unnecessary queries, but if you're going to be modifying the objects, you'll want to start fresh each time.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54242511%2fdjango-unit-testing-separating-unit-tests-without-querying-the-database-multipl%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Assuming you're using Django's testing framework, then you can do this using setUp().
      More about unittest.TestCase.setUp() here



      So your updated snippet would look like:



      from django.test import TestCase

      class MyTestCase(TestCase):
      def setUp(self):
      self.unfinished_task = Task.objects.get(tasked_with="Unfinished Test")

      def test_initial_task_deletion_status_is_none(self):
      self.assertIsNone(self.unfinished_task.delete_status)

      # Make sure a task's deletion status changes appropriately
      def test_unfinished_task_deletion_status_updates_appropriately(self):
      self.unfinished_task.timed_delete(delta=.1)
      self.assertIs(self.unfinished_task.delete_status, "Marked for Deletion")





      share|improve this answer




























        1














        Assuming you're using Django's testing framework, then you can do this using setUp().
        More about unittest.TestCase.setUp() here



        So your updated snippet would look like:



        from django.test import TestCase

        class MyTestCase(TestCase):
        def setUp(self):
        self.unfinished_task = Task.objects.get(tasked_with="Unfinished Test")

        def test_initial_task_deletion_status_is_none(self):
        self.assertIsNone(self.unfinished_task.delete_status)

        # Make sure a task's deletion status changes appropriately
        def test_unfinished_task_deletion_status_updates_appropriately(self):
        self.unfinished_task.timed_delete(delta=.1)
        self.assertIs(self.unfinished_task.delete_status, "Marked for Deletion")





        share|improve this answer


























          1












          1








          1







          Assuming you're using Django's testing framework, then you can do this using setUp().
          More about unittest.TestCase.setUp() here



          So your updated snippet would look like:



          from django.test import TestCase

          class MyTestCase(TestCase):
          def setUp(self):
          self.unfinished_task = Task.objects.get(tasked_with="Unfinished Test")

          def test_initial_task_deletion_status_is_none(self):
          self.assertIsNone(self.unfinished_task.delete_status)

          # Make sure a task's deletion status changes appropriately
          def test_unfinished_task_deletion_status_updates_appropriately(self):
          self.unfinished_task.timed_delete(delta=.1)
          self.assertIs(self.unfinished_task.delete_status, "Marked for Deletion")





          share|improve this answer













          Assuming you're using Django's testing framework, then you can do this using setUp().
          More about unittest.TestCase.setUp() here



          So your updated snippet would look like:



          from django.test import TestCase

          class MyTestCase(TestCase):
          def setUp(self):
          self.unfinished_task = Task.objects.get(tasked_with="Unfinished Test")

          def test_initial_task_deletion_status_is_none(self):
          self.assertIsNone(self.unfinished_task.delete_status)

          # Make sure a task's deletion status changes appropriately
          def test_unfinished_task_deletion_status_updates_appropriately(self):
          self.unfinished_task.timed_delete(delta=.1)
          self.assertIs(self.unfinished_task.delete_status, "Marked for Deletion")






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 17 at 20:09









          dhuidhui

          34227




          34227

























              1














              You can place the repeated line in the setUp method, and that will make your code less repetitive, but as DanielRoseman pointed out, it will still be run for each test, so you won't be using the same query result.



              You can place it in the setUpTestData method, and it will be run only once, before all the tests in MyTestCase, but then your unfinished_task object will be a class variable, shared across all the tests. In-memory modifications made to the object during one test will carry over into subsequent tests, and that is not what you want.



              In read-only tests, using setUpTestData is a good way to cut out unnecessary queries, but if you're going to be modifying the objects, you'll want to start fresh each time.






              share|improve this answer




























                1














                You can place the repeated line in the setUp method, and that will make your code less repetitive, but as DanielRoseman pointed out, it will still be run for each test, so you won't be using the same query result.



                You can place it in the setUpTestData method, and it will be run only once, before all the tests in MyTestCase, but then your unfinished_task object will be a class variable, shared across all the tests. In-memory modifications made to the object during one test will carry over into subsequent tests, and that is not what you want.



                In read-only tests, using setUpTestData is a good way to cut out unnecessary queries, but if you're going to be modifying the objects, you'll want to start fresh each time.






                share|improve this answer


























                  1












                  1








                  1







                  You can place the repeated line in the setUp method, and that will make your code less repetitive, but as DanielRoseman pointed out, it will still be run for each test, so you won't be using the same query result.



                  You can place it in the setUpTestData method, and it will be run only once, before all the tests in MyTestCase, but then your unfinished_task object will be a class variable, shared across all the tests. In-memory modifications made to the object during one test will carry over into subsequent tests, and that is not what you want.



                  In read-only tests, using setUpTestData is a good way to cut out unnecessary queries, but if you're going to be modifying the objects, you'll want to start fresh each time.






                  share|improve this answer













                  You can place the repeated line in the setUp method, and that will make your code less repetitive, but as DanielRoseman pointed out, it will still be run for each test, so you won't be using the same query result.



                  You can place it in the setUpTestData method, and it will be run only once, before all the tests in MyTestCase, but then your unfinished_task object will be a class variable, shared across all the tests. In-memory modifications made to the object during one test will carry over into subsequent tests, and that is not what you want.



                  In read-only tests, using setUpTestData is a good way to cut out unnecessary queries, but if you're going to be modifying the objects, you'll want to start fresh each time.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 19 at 6:12









                  Daniel HawkinsDaniel Hawkins

                  867910




                  867910






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54242511%2fdjango-unit-testing-separating-unit-tests-without-querying-the-database-multipl%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Callistus III

                      Plistias Cous

                      Index Sanctorum