Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. I'm fairly old fashioned at times ... but should I embrace unit testing?

I'm fairly old fashioned at times ... but should I embrace unit testing?

Scheduled Pinned Locked Moved The Lounge
testingbeta-testingtutorialquestion
54 Posts 38 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • OriginalGriffO OriginalGriff

    At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

        public static string Run()
            {
            try
                {
                testsRun = 0;
                testsPassed = 0;
                testsFailed = 0;
                outText.Clear();
                Range ra = new Range(0, 4);       // 
                Range rb = new Range(5, 9);       // Contiguous with ra
                Range rc = new Range(10, 14);     // Contiguous with rb
                Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                Range rf = new Range(16, 19);     // Not contiguous with anything.
                Range rg = new Range(0, 0);       // Single element.
                Range rh = new Range(1, 1);       // Single element.
                Range ri = new Range(2, 2);       // Single element.
                Range rj = new Range(0, 19);      // All elements.
                Range rk = new Range(0, 4);       // Identical to ra
    
                CheckInt(ra.Count, 5);
                CheckInt(ra.Min, 0);
                CheckInt(ra.Max, 4);
                CheckString(ra, "(0:4)");
                CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
    
                Check(Range.GetEmpty(), new int\[0\]);
    
                Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                CheckInt(ra.UnionWith(rc).Count, 10);
                CheckInt(ra.UnionWith(rc).Min, 0);
                CheckInt(ra.UnionWith
    
    Z Offline
    Z Offline
    ZevSpitz
    wrote on last edited by
    #29

    For me, there are two primary benefits: 1. Communicating intent -- using a well-known testing framework (as opposed to rolling your own) more easily communicates to other people what the testing code is supposed to do, because it's using a standard language. 2. Integration -- such as with an automated build pipeline, or Visual Studio's Test Explorer.

    1 Reply Last reply
    0
    • R RickZeeland

      We did some unit testing with Nunit in the past, but it proved too time-consuming to keep up with the rapid pace of changes of our software. So I think the idea is good, but not for our situation (small team, rapid changes) I also shiver when I read articles about "Test Driven Development" :-\ Oh, and of course the obligatory: Slant: best-unit-testing-frameworks-for-net[^]

      D Offline
      D Offline
      Davyd McColl
      wrote on last edited by
      #30

      I've heard this cry before: "the tests are brittle! every time we update prod code, we have to fix heaps of tests!" and it usually leads to people feeling that unit testing "doesn't work for them". The situation you describe is usually indicative of just not having had someone with extensive unit-testing experience to help write the tests in a sustainable manner. It's not a swipe at the people writing the code - it's really easy to get to the state where an update to code breaks a hundred tests without the experience on how to mitigate that. It's also easier (imo) to write sustainable tests if you're writing them _first_, because this drives your software design to be more testable - and often, produce more resilient tests. Following SOLID principles helps a lot because it means you can mock out layers underneath the code being tested instead of relying on actual behaviors all the time. It also means you can focus testing on smaller units up-front. If you decide to give it another go, try leading with this mindset: if these tests are brittle, how do we make it so that they aren't? What architectural/design changes should we do to facilitate resilient, informative tests?

      ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

      R 1 Reply Last reply
      0
      • OriginalGriffO OriginalGriff

        At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

            public static string Run()
                {
                try
                    {
                    testsRun = 0;
                    testsPassed = 0;
                    testsFailed = 0;
                    outText.Clear();
                    Range ra = new Range(0, 4);       // 
                    Range rb = new Range(5, 9);       // Contiguous with ra
                    Range rc = new Range(10, 14);     // Contiguous with rb
                    Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                    Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                    Range rf = new Range(16, 19);     // Not contiguous with anything.
                    Range rg = new Range(0, 0);       // Single element.
                    Range rh = new Range(1, 1);       // Single element.
                    Range ri = new Range(2, 2);       // Single element.
                    Range rj = new Range(0, 19);      // All elements.
                    Range rk = new Range(0, 4);       // Identical to ra
        
                    CheckInt(ra.Count, 5);
                    CheckInt(ra.Min, 0);
                    CheckInt(ra.Max, 4);
                    CheckString(ra, "(0:4)");
                    CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
        
                    Check(Range.GetEmpty(), new int\[0\]);
        
                    Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                    Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                    Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                    Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                    Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                    Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                    Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                    Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                    Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                    Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                    CheckInt(ra.UnionWith(rc).Count, 10);
                    CheckInt(ra.UnionWith(rc).Min, 0);
                    CheckInt(ra.UnionWith
        
        D Offline
        D Offline
        Davyd McColl
        wrote on last edited by
        #31

        Any testing is far better than no testing. You could put this test into an automated runner and have at it - you have "unit tests" where the definition of "unit" is stretched out a little :D and you already gain something out of this - if it's run in a CI environment, you get to catch bugs before they go out. Even if you just run them yourself, you get that benefit, though you could forget. Now, if you decide that you have the time and energy to convert to more focused tests, or decide that new tests could be written in a more focused manner, there are advantages: - more focused test failures - failures now tell you exactly _what_ has failed, instead of just "there's been a regression" - reporting output showing [Test Name] [passed/failed] for posterity - easier to fix the issue - find the single test, look at what it does, what environment it had to set up, and run through just that code path in the debugger to find the issue. I'll vote up unit tests, especially written _before_ the prod code (TDD!) any day of the week - and the weekend! :D

        ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

        1 Reply Last reply
        0
        • D Davyd McColl

          I've heard this cry before: "the tests are brittle! every time we update prod code, we have to fix heaps of tests!" and it usually leads to people feeling that unit testing "doesn't work for them". The situation you describe is usually indicative of just not having had someone with extensive unit-testing experience to help write the tests in a sustainable manner. It's not a swipe at the people writing the code - it's really easy to get to the state where an update to code breaks a hundred tests without the experience on how to mitigate that. It's also easier (imo) to write sustainable tests if you're writing them _first_, because this drives your software design to be more testable - and often, produce more resilient tests. Following SOLID principles helps a lot because it means you can mock out layers underneath the code being tested instead of relying on actual behaviors all the time. It also means you can focus testing on smaller units up-front. If you decide to give it another go, try leading with this mindset: if these tests are brittle, how do we make it so that they aren't? What architectural/design changes should we do to facilitate resilient, informative tests?

          ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

          R Offline
          R Offline
          RickZeeland
          wrote on last edited by
          #32

          Guess it depends on how disciplined the co-workers are, in my team they are not, they're a real wild bunch that break the API almost every day :-\

          D 1 Reply Last reply
          0
          • R RickZeeland

            Guess it depends on how disciplined the co-workers are, in my team they are not, they're a real wild bunch that break the API almost every day :-\

            D Offline
            D Offline
            Davyd McColl
            wrote on last edited by
            #33

            If you have good refactoring available, that can help (Rider/ReSharper) because at least it will try to update all usages - often with little or no manual work involved. If you find that you're often breaking the shape of your API, then create a class in your tests - an adapter - that keeps the api exposed to the tests the same, providing a central place to respond to breaking changes. However, if your API is constantly changing (mutating, not just being expanded upon), I really hope there's only one consumer - I'd hate to be the one having to chase that down the line! This could suggest altering the dev behavior to not be so "wild", or just making people responsible for completing the refactor themselves - if there's a designated "unit test person" in the group and no-one else bothers to write tests, that's never going to end well.

            ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

            R 1 Reply Last reply
            0
            • D Davyd McColl

              If you have good refactoring available, that can help (Rider/ReSharper) because at least it will try to update all usages - often with little or no manual work involved. If you find that you're often breaking the shape of your API, then create a class in your tests - an adapter - that keeps the api exposed to the tests the same, providing a central place to respond to breaking changes. However, if your API is constantly changing (mutating, not just being expanded upon), I really hope there's only one consumer - I'd hate to be the one having to chase that down the line! This could suggest altering the dev behavior to not be so "wild", or just making people responsible for completing the refactor themselves - if there's a designated "unit test person" in the group and no-one else bothers to write tests, that's never going to end well.

              ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

              R Offline
              R Offline
              RickZeeland
              wrote on last edited by
              #34

              I installed this utility (which works really well) on our TeamCity builder to check for API changes: GitHub - arlm/apichange: Fork of the codeplex API Change repository[^] But they just keep breaking away despite the warnings :sigh:

              D 1 Reply Last reply
              0
              • R RickZeeland

                I installed this utility (which works really well) on our TeamCity builder to check for API changes: GitHub - arlm/apichange: Fork of the codeplex API Change repository[^] But they just keep breaking away despite the warnings :sigh:

                D Offline
                D Offline
                Davyd McColl
                wrote on last edited by
                #35

                That's a team problem then. Just like how git can't police people into making concise, responsible commits in the right places, and wasn't designed to, that tool is to warn people _who actually care when stuff breaks_. If your cowboys don't care, that's a whole other issue that needs to be figured out, because they're creating work for other people. That doesn't mean that an api _cannot_ change - it means that the people involved have to do so responsibly - eg by providing overloads, or at least trying to keep existing signatures as intact as possible. I'm not a fan of it, but perhaps you need something like gated checkins. I'd much rather have the team chat where we all come to an agreement on how we're going to work together though. You need to sell this idea of improving team cohesion up the chain - because right now, the cowboys are costing the company money when other people have to deal with their fallout.

                ------------------------------------------------ If you say that getting the money is the most important thing You will spend your life completely wasting your time You will be doing things you don't like doing In order to go on living That is, to go on doing things you don't like doing Which is stupid. - Alan Watts https://www.youtube.com/watch?v=-gXTZM\_uPMY

                1 Reply Last reply
                0
                • OriginalGriffO OriginalGriff

                  At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                      public static string Run()
                          {
                          try
                              {
                              testsRun = 0;
                              testsPassed = 0;
                              testsFailed = 0;
                              outText.Clear();
                              Range ra = new Range(0, 4);       // 
                              Range rb = new Range(5, 9);       // Contiguous with ra
                              Range rc = new Range(10, 14);     // Contiguous with rb
                              Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                              Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                              Range rf = new Range(16, 19);     // Not contiguous with anything.
                              Range rg = new Range(0, 0);       // Single element.
                              Range rh = new Range(1, 1);       // Single element.
                              Range ri = new Range(2, 2);       // Single element.
                              Range rj = new Range(0, 19);      // All elements.
                              Range rk = new Range(0, 4);       // Identical to ra
                  
                              CheckInt(ra.Count, 5);
                              CheckInt(ra.Min, 0);
                              CheckInt(ra.Max, 4);
                              CheckString(ra, "(0:4)");
                              CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                  
                              Check(Range.GetEmpty(), new int\[0\]);
                  
                              Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                              Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                              Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                              Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                              Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                              Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                              Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                              Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                              Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                              Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                              CheckInt(ra.UnionWith(rc).Count, 10);
                              CheckInt(ra.UnionWith(rc).Min, 0);
                              CheckInt(ra.UnionWith
                  
                  R Offline
                  R Offline
                  realJSOP
                  wrote on last edited by
                  #36

                  Agile programming doesn't lend itself to unit testing. Since the "customer" is involved, they are only concerned about the speed of development, and whether or not a task can be completed within a sprint. For us, a sprint also includes the time testers and customers need to test a given task. We don't have any time to do unit test development because we're just trying to get the code written. Another aspect is that most of our business rules are implemented in the database. Even if they weren't, they change (at the customer's request) so often that writing a unit test for a given business rule is pointless. We would have to write an app that did nothing but spot-check data (we have 54 million records, and it would take HOURS to check them all). Our apps are all web apps, and we have way over the top security restrictions. - We can't use the browser dev console on test, QA, or production environments - We don't have any access to the databases on those environments - All four environments (the ones already cited, and dev) are configured differently in terms of memory, cpu's, hand hard drive space and number of servers. If something happens on test/qa/prod, but not on dev, it's a freakin nightmare because we can't use the dev console on to see what's happening in the javascript to narrow it down. Our infrastructure is the cause of many of our problems, and we can't leverage any tools to find out what's wrong, and unit testing won't help in that regard.

                  ".45 ACP - because shooting twice is just silly" - JSOP, 2010
                  -----
                  You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
                  -----
                  When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013

                  1 Reply Last reply
                  0
                  • OriginalGriffO OriginalGriff

                    At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                        public static string Run()
                            {
                            try
                                {
                                testsRun = 0;
                                testsPassed = 0;
                                testsFailed = 0;
                                outText.Clear();
                                Range ra = new Range(0, 4);       // 
                                Range rb = new Range(5, 9);       // Contiguous with ra
                                Range rc = new Range(10, 14);     // Contiguous with rb
                                Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                Range rf = new Range(16, 19);     // Not contiguous with anything.
                                Range rg = new Range(0, 0);       // Single element.
                                Range rh = new Range(1, 1);       // Single element.
                                Range ri = new Range(2, 2);       // Single element.
                                Range rj = new Range(0, 19);      // All elements.
                                Range rk = new Range(0, 4);       // Identical to ra
                    
                                CheckInt(ra.Count, 5);
                                CheckInt(ra.Min, 0);
                                CheckInt(ra.Max, 4);
                                CheckString(ra, "(0:4)");
                                CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                    
                                Check(Range.GetEmpty(), new int\[0\]);
                    
                                Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                CheckInt(ra.UnionWith(rc).Count, 10);
                                CheckInt(ra.UnionWith(rc).Min, 0);
                                CheckInt(ra.UnionWith
                    
                    Sander RosselS Offline
                    Sander RosselS Offline
                    Sander Rossel
                    wrote on last edited by
                    #37

                    Read the stuff at the top of the page: the Lounge is not for coding questions. Post it here instead: Ask a Question[^] Ignoring the rules and annoying people you want free help from is not a good idea ... In addition, when you post your question give us just the relevant code fragments, and paste them directly into the question. Without it, we have no idea what you have tried, and it saves us teh effort of trying to work out which bits of your whole code are important. The more you help us to help you, the better the answer you can get. Well, well, well, how the turntables!* :D * I know it's not completely relevant, but I probably won't get a better chance than this.

                    Best, Sander Azure DevOps Succinctly (free eBook) Azure Serverless Succinctly (free eBook) Migrating Apps to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript

                    OriginalGriffO 1 Reply Last reply
                    0
                    • Sander RosselS Sander Rossel

                      Read the stuff at the top of the page: the Lounge is not for coding questions. Post it here instead: Ask a Question[^] Ignoring the rules and annoying people you want free help from is not a good idea ... In addition, when you post your question give us just the relevant code fragments, and paste them directly into the question. Without it, we have no idea what you have tried, and it saves us teh effort of trying to work out which bits of your whole code are important. The more you help us to help you, the better the answer you can get. Well, well, well, how the turntables!* :D * I know it's not completely relevant, but I probably won't get a better chance than this.

                      Best, Sander Azure DevOps Succinctly (free eBook) Azure Serverless Succinctly (free eBook) Migrating Apps to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript

                      OriginalGriffO Offline
                      OriginalGriffO Offline
                      OriginalGriff
                      wrote on last edited by
                      #38

                      :laugh:

                      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

                      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                      1 Reply Last reply
                      0
                      • OriginalGriffO OriginalGriff

                        At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                            public static string Run()
                                {
                                try
                                    {
                                    testsRun = 0;
                                    testsPassed = 0;
                                    testsFailed = 0;
                                    outText.Clear();
                                    Range ra = new Range(0, 4);       // 
                                    Range rb = new Range(5, 9);       // Contiguous with ra
                                    Range rc = new Range(10, 14);     // Contiguous with rb
                                    Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                    Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                    Range rf = new Range(16, 19);     // Not contiguous with anything.
                                    Range rg = new Range(0, 0);       // Single element.
                                    Range rh = new Range(1, 1);       // Single element.
                                    Range ri = new Range(2, 2);       // Single element.
                                    Range rj = new Range(0, 19);      // All elements.
                                    Range rk = new Range(0, 4);       // Identical to ra
                        
                                    CheckInt(ra.Count, 5);
                                    CheckInt(ra.Min, 0);
                                    CheckInt(ra.Max, 4);
                                    CheckString(ra, "(0:4)");
                                    CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                        
                                    Check(Range.GetEmpty(), new int\[0\]);
                        
                                    Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                    Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                    Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                    Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                    Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                    Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                    Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                    Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                    Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                    Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                    CheckInt(ra.UnionWith(rc).Count, 10);
                                    CheckInt(ra.UnionWith(rc).Min, 0);
                                    CheckInt(ra.UnionWith
                        
                        C Offline
                        C Offline
                        Cpichols
                        wrote on last edited by
                        #39

                        I'm so old-fashioned that I only recently learned about unit tests and only now learned about automatic testing outside of that. I was out of the mainstream coding world for a quarter of a century while I raised my 6, which is one reason that I'm here - to learn. I think that you should do what works for you unless you are required to do it otherwise. For me and the coding environment I work in, that means lots of echos and prints - var dumping, but that's legacy code for you - don't stir the pot too much xD :laugh:

                        1 Reply Last reply
                        0
                        • OriginalGriffO OriginalGriff

                          At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                              public static string Run()
                                  {
                                  try
                                      {
                                      testsRun = 0;
                                      testsPassed = 0;
                                      testsFailed = 0;
                                      outText.Clear();
                                      Range ra = new Range(0, 4);       // 
                                      Range rb = new Range(5, 9);       // Contiguous with ra
                                      Range rc = new Range(10, 14);     // Contiguous with rb
                                      Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                      Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                      Range rf = new Range(16, 19);     // Not contiguous with anything.
                                      Range rg = new Range(0, 0);       // Single element.
                                      Range rh = new Range(1, 1);       // Single element.
                                      Range ri = new Range(2, 2);       // Single element.
                                      Range rj = new Range(0, 19);      // All elements.
                                      Range rk = new Range(0, 4);       // Identical to ra
                          
                                      CheckInt(ra.Count, 5);
                                      CheckInt(ra.Min, 0);
                                      CheckInt(ra.Max, 4);
                                      CheckString(ra, "(0:4)");
                                      CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                          
                                      Check(Range.GetEmpty(), new int\[0\]);
                          
                                      Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                      Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                      Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                      Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                      Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                      Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                      Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                      Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                      Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                      Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                      CheckInt(ra.UnionWith(rc).Count, 10);
                                      CheckInt(ra.UnionWith(rc).Min, 0);
                                      CheckInt(ra.UnionWith
                          
                          M Offline
                          M Offline
                          Member 14840496
                          wrote on last edited by
                          #40

                          Unit testing tests for code that is primal and isn't the cause of problems. Test that the value I passed you is a bool. What does cause problems are things like Excel cells that are missing or contains the wrong data. Data configurations that you did not plan/account for. Users that do things you did not think they would ever do. Exceptions you missed that blew up the app. And lets not forget that you are writing test code to test your code. :wtf:

                          1 Reply Last reply
                          0
                          • OriginalGriffO OriginalGriff

                            At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                public static string Run()
                                    {
                                    try
                                        {
                                        testsRun = 0;
                                        testsPassed = 0;
                                        testsFailed = 0;
                                        outText.Clear();
                                        Range ra = new Range(0, 4);       // 
                                        Range rb = new Range(5, 9);       // Contiguous with ra
                                        Range rc = new Range(10, 14);     // Contiguous with rb
                                        Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                        Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                        Range rf = new Range(16, 19);     // Not contiguous with anything.
                                        Range rg = new Range(0, 0);       // Single element.
                                        Range rh = new Range(1, 1);       // Single element.
                                        Range ri = new Range(2, 2);       // Single element.
                                        Range rj = new Range(0, 19);      // All elements.
                                        Range rk = new Range(0, 4);       // Identical to ra
                            
                                        CheckInt(ra.Count, 5);
                                        CheckInt(ra.Min, 0);
                                        CheckInt(ra.Max, 4);
                                        CheckString(ra, "(0:4)");
                                        CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                            
                                        Check(Range.GetEmpty(), new int\[0\]);
                            
                                        Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                        Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                        Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                        Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                        Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                        Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                        Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                        Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                        Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                        Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                        CheckInt(ra.UnionWith(rc).Count, 10);
                                        CheckInt(ra.UnionWith(rc).Min, 0);
                                        CheckInt(ra.UnionWith
                            
                            P Offline
                            P Offline
                            Peter Kelley 2021
                            wrote on last edited by
                            #41

                            It sounds like what you do is exactly what unit testing is. Perhaps some of the other parts of the Capitalized-Letter "Unit Testing" practices that might come to mind are > keeping selected relevent unit test cases for reuse in either/both future development or qa builds. > running the tests *automatically* against a shared build, especially during heavier development times, shared or otherwise. I don't think these are truly new, but have become more widely recognized and adapted for practically any language. We used to do this stuff in COBOL. Beware of when any programmer makes automating a test ritually - if it's automatic, there should be a reason for the test. Some people mistake statistics for quality. If a case doesn't make sense anymore get rid of the test(s). What's great is there are so much shared knowledge and experience. Frameworks and suggested practices abound. And if you don't happen to use a framework for it, there's really no issue, and it has just as much relevence. Automating tests is essential to expediting refactoring code. It gives me some assurance that unexpected behaviors haven't popped up. Some tests behave like functioning documentation to remind me in the future just how this thing works.

                            1 Reply Last reply
                            0
                            • OriginalGriffO OriginalGriff

                              At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                  public static string Run()
                                      {
                                      try
                                          {
                                          testsRun = 0;
                                          testsPassed = 0;
                                          testsFailed = 0;
                                          outText.Clear();
                                          Range ra = new Range(0, 4);       // 
                                          Range rb = new Range(5, 9);       // Contiguous with ra
                                          Range rc = new Range(10, 14);     // Contiguous with rb
                                          Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                          Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                          Range rf = new Range(16, 19);     // Not contiguous with anything.
                                          Range rg = new Range(0, 0);       // Single element.
                                          Range rh = new Range(1, 1);       // Single element.
                                          Range ri = new Range(2, 2);       // Single element.
                                          Range rj = new Range(0, 19);      // All elements.
                                          Range rk = new Range(0, 4);       // Identical to ra
                              
                                          CheckInt(ra.Count, 5);
                                          CheckInt(ra.Min, 0);
                                          CheckInt(ra.Max, 4);
                                          CheckString(ra, "(0:4)");
                                          CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                              
                                          Check(Range.GetEmpty(), new int\[0\]);
                              
                                          Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                          Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                          Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                          Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                          Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                          Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                          Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                          Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                          Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                          Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                          CheckInt(ra.UnionWith(rc).Count, 10);
                                          CheckInt(ra.UnionWith(rc).Min, 0);
                                          CheckInt(ra.UnionWith
                              
                              J Offline
                              J Offline
                              Jeroen_R
                              wrote on last edited by
                              #42

                              I used to be skeptical about unit testing and TDD/BDD. Mainly because it felt like it was too much work. Then 2 things happened more or less simultaneously: I got to work on a huge code base that had a 85% unit test coverage and I saw this talk by Ian Cooper/[^] The talk showed me how you can write unit tests that aren't tightly coupled to the implementation of your code, which makes them less brittle and only subject to change when your code has functional changes. The big codebase showed me that it is much easier and less risky (and will therefore be done more often) to make bigger changes and/or refactorings when you know your unit test suite will yell at you when you make a mistake.

                              1 Reply Last reply
                              0
                              • OriginalGriffO OriginalGriff

                                At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                    public static string Run()
                                        {
                                        try
                                            {
                                            testsRun = 0;
                                            testsPassed = 0;
                                            testsFailed = 0;
                                            outText.Clear();
                                            Range ra = new Range(0, 4);       // 
                                            Range rb = new Range(5, 9);       // Contiguous with ra
                                            Range rc = new Range(10, 14);     // Contiguous with rb
                                            Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                            Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                            Range rf = new Range(16, 19);     // Not contiguous with anything.
                                            Range rg = new Range(0, 0);       // Single element.
                                            Range rh = new Range(1, 1);       // Single element.
                                            Range ri = new Range(2, 2);       // Single element.
                                            Range rj = new Range(0, 19);      // All elements.
                                            Range rk = new Range(0, 4);       // Identical to ra
                                
                                            CheckInt(ra.Count, 5);
                                            CheckInt(ra.Min, 0);
                                            CheckInt(ra.Max, 4);
                                            CheckString(ra, "(0:4)");
                                            CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                                
                                            Check(Range.GetEmpty(), new int\[0\]);
                                
                                            Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                            Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                            Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                            Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                            Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                            Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                            Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                            Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                            Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                            Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                            CheckInt(ra.UnionWith(rc).Count, 10);
                                            CheckInt(ra.UnionWith(rc).Min, 0);
                                            CheckInt(ra.UnionWith
                                
                                M Offline
                                M Offline
                                Matt Bond
                                wrote on last edited by
                                #43

                                We code a extremely large enterprise program (multiple EXE's, multiple Windows services, etc.). We use automatic unit testing in only 2 places. Both of them are for complex calculations with a handful of inputs and outputs. There are billions of possible logic paths. The unit tests included about a 1000 sets of inputs that covered common scenarios and edge cases. That way if we had to fix the calculations, we knew that they still worked by just running the unit tests. These are not automatically run. Dev's just run them if they change the matching code. We also use an automatic testing suite to test the program. There is a separate team that creates and maintains that suite. The Dev's never talk to them. I have no idea what they do or how they do it. It took 2+ years for them to get about 90% test coverage. We consider running this automatic test suite as smoke testing.

                                Bond Keep all things as simple as possible, but no simpler. -said someone, somewhere

                                1 Reply Last reply
                                0
                                • OriginalGriffO OriginalGriff

                                  At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                      public static string Run()
                                          {
                                          try
                                              {
                                              testsRun = 0;
                                              testsPassed = 0;
                                              testsFailed = 0;
                                              outText.Clear();
                                              Range ra = new Range(0, 4);       // 
                                              Range rb = new Range(5, 9);       // Contiguous with ra
                                              Range rc = new Range(10, 14);     // Contiguous with rb
                                              Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                              Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                              Range rf = new Range(16, 19);     // Not contiguous with anything.
                                              Range rg = new Range(0, 0);       // Single element.
                                              Range rh = new Range(1, 1);       // Single element.
                                              Range ri = new Range(2, 2);       // Single element.
                                              Range rj = new Range(0, 19);      // All elements.
                                              Range rk = new Range(0, 4);       // Identical to ra
                                  
                                              CheckInt(ra.Count, 5);
                                              CheckInt(ra.Min, 0);
                                              CheckInt(ra.Max, 4);
                                              CheckString(ra, "(0:4)");
                                              CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                                  
                                              Check(Range.GetEmpty(), new int\[0\]);
                                  
                                              Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                              Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                              Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                              Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                              Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                              Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                              Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                              Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                              Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                              Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                              CheckInt(ra.UnionWith(rc).Count, 10);
                                              CheckInt(ra.UnionWith(rc).Min, 0);
                                              CheckInt(ra.UnionWith
                                  
                                  B Offline
                                  B Offline
                                  Bruce Greene
                                  wrote on last edited by
                                  #44

                                  I've been writing C/C++/C# professionally now for 30 years in the critical realm of industrial automation. I've never done formal unit testing. I write code carefully and deliberately, refactoring as necessary until it looks clean and efficient. I then run some tests to confirm the expected functionality - and then I move on. The key to success is following SOLID principles and not moving on until the code is clean and methods/variables are well named. A method that works will continue to work, and clean well-named code is easy to work with later.

                                  M 1 Reply Last reply
                                  0
                                  • OriginalGriffO OriginalGriff

                                    At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                        public static string Run()
                                            {
                                            try
                                                {
                                                testsRun = 0;
                                                testsPassed = 0;
                                                testsFailed = 0;
                                                outText.Clear();
                                                Range ra = new Range(0, 4);       // 
                                                Range rb = new Range(5, 9);       // Contiguous with ra
                                                Range rc = new Range(10, 14);     // Contiguous with rb
                                                Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                                Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                                Range rf = new Range(16, 19);     // Not contiguous with anything.
                                                Range rg = new Range(0, 0);       // Single element.
                                                Range rh = new Range(1, 1);       // Single element.
                                                Range ri = new Range(2, 2);       // Single element.
                                                Range rj = new Range(0, 19);      // All elements.
                                                Range rk = new Range(0, 4);       // Identical to ra
                                    
                                                CheckInt(ra.Count, 5);
                                                CheckInt(ra.Min, 0);
                                                CheckInt(ra.Max, 4);
                                                CheckString(ra, "(0:4)");
                                                CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                                    
                                                Check(Range.GetEmpty(), new int\[0\]);
                                    
                                                Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                                Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                                Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                                Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                                Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                                Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                                Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                                Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                                Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                                Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                                CheckInt(ra.UnionWith(rc).Count, 10);
                                                CheckInt(ra.UnionWith(rc).Min, 0);
                                                CheckInt(ra.UnionWith
                                    
                                    S Offline
                                    S Offline
                                    SeattleC
                                    wrote on last edited by
                                    #45

                                    I love unit testing. When I'm not working with a testing framework, every class has a static method for testing (static, so it isn't linked into the executable unless you call tests). I test things when I change things. The two projects I worked on that had the lowest defect density both had good unit tests and a desire to make them better. Did I mention that I love unit testing?

                                    1 Reply Last reply
                                    0
                                    • OriginalGriffO OriginalGriff

                                      At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                          public static string Run()
                                              {
                                              try
                                                  {
                                                  testsRun = 0;
                                                  testsPassed = 0;
                                                  testsFailed = 0;
                                                  outText.Clear();
                                                  Range ra = new Range(0, 4);       // 
                                                  Range rb = new Range(5, 9);       // Contiguous with ra
                                                  Range rc = new Range(10, 14);     // Contiguous with rb
                                                  Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                                  Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                                  Range rf = new Range(16, 19);     // Not contiguous with anything.
                                                  Range rg = new Range(0, 0);       // Single element.
                                                  Range rh = new Range(1, 1);       // Single element.
                                                  Range ri = new Range(2, 2);       // Single element.
                                                  Range rj = new Range(0, 19);      // All elements.
                                                  Range rk = new Range(0, 4);       // Identical to ra
                                      
                                                  CheckInt(ra.Count, 5);
                                                  CheckInt(ra.Min, 0);
                                                  CheckInt(ra.Max, 4);
                                                  CheckString(ra, "(0:4)");
                                                  CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                                      
                                                  Check(Range.GetEmpty(), new int\[0\]);
                                      
                                                  Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                                  Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                                  Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                                  Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                                  Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                                  Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                                  Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                                  Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                                  Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                                  Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                                  CheckInt(ra.UnionWith(rc).Count, 10);
                                                  CheckInt(ra.UnionWith(rc).Min, 0);
                                                  CheckInt(ra.UnionWith
                                      
                                      M Offline
                                      M Offline
                                      Matt McGuire
                                      wrote on last edited by
                                      #46

                                      I've always been a single dev, once or twice working with another dev at jobs. I've never bothered with Unit Testing (when it started to become popular), because of the nature of the embedded or control software made it almost impossible to simulate real world situations. the code had to be correct also because of the litigation that could happen if something is even a little off and you destroy product. Although I'm not building that stuff as much anymore, I still go by my old habits of building code and test running it early as possible. some more complex things will get a temporary project to test the code and once I'm happy I'll integrate it into the main project. I rarely have bug issues and still have software out there running since 2001-ish. this is my first job using SQL that I've never needed before in my previous jobs, but I still find when making stored procedures or complex views that I follow my normal build, test, and expand until the final SPROC is completed. It's nice because it's always a testable 'unit' to verify results separate from the software logic. this place I'm working for now had so much embedded inline SQL in the legacy code, so It's almost impossible to test out separately from the program logic, so it's all getting replaced slowly. tldr; I'm old and stubborn, and my process has been working great for me forever, I see no need to use Unit Testing at this point.

                                      1 Reply Last reply
                                      0
                                      • OriginalGriffO OriginalGriff

                                        At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:

                                            public static string Run()
                                                {
                                                try
                                                    {
                                                    testsRun = 0;
                                                    testsPassed = 0;
                                                    testsFailed = 0;
                                                    outText.Clear();
                                                    Range ra = new Range(0, 4);       // 
                                                    Range rb = new Range(5, 9);       // Contiguous with ra
                                                    Range rc = new Range(10, 14);     // Contiguous with rb
                                                    Range rd = new Range(1, 3);       // Intersects ra, not contiguous with rb
                                                    Range re = new Range(6, 8);       // Intersects rb, not contiguous with rc
                                                    Range rf = new Range(16, 19);     // Not contiguous with anything.
                                                    Range rg = new Range(0, 0);       // Single element.
                                                    Range rh = new Range(1, 1);       // Single element.
                                                    Range ri = new Range(2, 2);       // Single element.
                                                    Range rj = new Range(0, 19);      // All elements.
                                                    Range rk = new Range(0, 4);       // Identical to ra
                                        
                                                    CheckInt(ra.Count, 5);
                                                    CheckInt(ra.Min, 0);
                                                    CheckInt(ra.Max, 4);
                                                    CheckString(ra, "(0:4)");
                                                    CheckString(ra.UnionWith(re), "(0:4) | (6:8)");
                                        
                                                    Check(Range.GetEmpty(), new int\[0\]);
                                        
                                                    Check(ra, new int\[\] { 0, 1, 2, 3, 4, });
                                                    Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 });
                                                    Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 });
                                                    Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
                                                    Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 });
                                                    Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 });
                                                    Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 });
                                                    Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 });
                                                    Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 });
                                                    Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 });
                                                    CheckInt(ra.UnionWith(rc).Count, 10);
                                                    CheckInt(ra.UnionWith(rc).Min, 0);
                                                    CheckInt(ra.UnionWith
                                        
                                        C Offline
                                        C Offline
                                        CosmoSpacely
                                        wrote on last edited by
                                        #47

                                        Uhhhh, you have already embraced unit testing. Your static class *is* a unit test. Otherwise known as a device to keep programmers sane(ish). It doesn't integrate with frameworks or IDE integration, but it's a unit test.

                                        1 Reply Last reply
                                        0
                                        • L lmoelleb

                                          TDD: 1. Write a test 2. Start writing the code 3. Change the test 4. Write some more code 5. Go back to step 3 as required 6. Finish the code. 7. Fix the bugs in the test. That said, thinking about tests early do help me think "what are the edge cases here" etc. And a few times I do write test first if it is obvious what they should be. As with anything, as soon as you become pedantic you are in for pain.

                                          T Offline
                                          T Offline
                                          TNCaver
                                          wrote on last edited by
                                          #48

                                          lmoelleb wrote:

                                          thinking about tests early do help me think "what are the edge cases here" etc.

                                          I think of those things while writing the code inside the try{} block and inside the catch{} block. I don't see any benefit to doubling my work for the little, if any, benefit gained by adding a unit test. Major companies like MS have been using TDD for years now, and their software still has bugs. I'm not impressed.

                                          If you think 'goto' is evil, try writing an Assembly program without JMP.

                                          L 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups