5 ms·
Let's say you change your function by adding a new parameter, or you modify the order/type of existing parameters. How does your REPL save you, then? You can ma
by mercurial 13y ago
Let's say you change your function by adding a new parameter, or you modify the order/type of existing parameters. How does your REPL save you, then? You can make sure that your new function works correctly, but not that all call sites are correct. In my experience, not that many codebases have "high-level integration tests", which are kind of an orthogonal issue compared to unit tests (you still need unit tests if you want maintainable Haskell, in spite of the type system and REPL).
- yogthos 13y agoThe REPL lets you test any call sites immediately after you make a change. I do this all the time at work. Let's say I change a function that accesses the database, I can update the function then update the call sites and run them right there and then. At least in Clojure, the REPL is integrated in the IDE. I can use the IDE to tell me where the call sites are what references the function, jump to definition, etc. Then I can send code from the editor directly to the REPL to test it out. I use Intellij with the Cursive (http://cursiveclojure.com/ http://cursiveclojure.com/) plugin, but you can do the same thing with Emacs and Eclipse. My experience is that unit tests make sense in some scenarios, but not in every situation. On the other hand, high level integration tests act as a contract for your application. You should have these regardless of whether you're working with a dynamic or a static language.
- mercurial 13y ago> The REPL lets you test any call sites immediately after you make a change. I do this all the time at work. Let's say I change a function that accesses the database, I can update the function then update the call sites and run them right there and then. At least the ones you know about. Now, take your codebase to 100k lines, 75% of which you didn't write. Good luck. Wrt to integration tests: they're a pain to set up, and the complexity creeps it really easily. It's straightforward to unit-test edge cases, but the combination of layers makes it much more difficult to rely on integration tests for this kind of thing. Plus, integration tests usually take a long time to run. Rapid feedback is important.
- yogthos 13y agoThe code base I'm working on has been developed for about 3 years by a team of 4 people. I have no trouble navigating it, nor does anybody else on the team. If you're working with a half decent IDE, it can do things like tracking down function usages for you very easily. >Wrt to integration tests: they're a pain to set up, and the complexity creeps it really easily. That has not been my experience at all. Clojure has very nice testing frameworks that makes this trivial. >It's straightforward to unit-test edge cases, but the combination of layers makes it much more difficult to rely on integration tests for this kind of thing. The REPL allows doing a lot of what unit tests are normally used for. When you make a change you test it live in the REPL. This is no different from running a unit test. >Plus, integration tests usually take a long time to run. Rapid feedback is important. Hence why you don't run them all the time. The REPL provides you with rapid feedback, much more rapid than running unit tests I might add. Meanwhile, the integration tests are used for overall sanity testing.
- jongraehl 13y ago> When you make a change you test it live in the REPL. This is no different from running a unit test. What?
- yogthos 13y agoLet's say I have a function that pulls some data from the database and transforms it in some way. I can run the original function and capture its output. Then I can write an updated function, see what its output is, I can compare them visually to ensure the change I made works as intended. When you don't have a REPL the only way to do this is by writing a test and running it once you've made the change. In fact, you can use the code from the tests you write in the REPL to create a unit test for later. The difference is that the REPL feedback loop is much tighter.
- mercurial 13y ago> The code base I'm working on has been developed for about 3 years by a team of 4 people. I have no trouble navigating it, nor does anybody else on the team. Good. Except, next time you hire somebody, you may get accidents. > If you're working with a half decent IDE, it can do things like tracking down function usages for you very easily. Oh, certainly, but it kind of invalidates your claim that REPL + integration tests is enough to maintain a codebase. > That has not been my experience at all. Clojure has very nice testing frameworks that makes this trivial. Hm. I've worked with "very nice testing frameworks", but I'm not aware of any which helps with the two main issues that crop up when you create integration tests: - integration with external tools (external database, LDAP...) - amount of setup in your application necessary prior to running scenarios > The REPL allows doing a lot of what unit tests are normally used for. When you make a change you test it live in the REPL. This is no different from running a unit test. Well, considering that a well-tested unit of code (ie, what you put in a single file) is usually dwarfed in size by the test code itself, because you're testing a lot of scenarios, then you either spend an unholy amount of time in the REPL, or you don't test everything. Which brings me to my second point: unit tests will run the same tests every single time. And even better, everybody in the team will run the same unit tests every single time. A REPL is no substitute for unit tests. I'm not saying it's not useful, because it allows you to validate an idea fairly quickly, especially in simple cases, but it is absolutely not suited to validate the correctness of a piece of code. > Hence why you don't run them all the time. The REPL provides you with rapid feedback, much more rapid than running unit tests I might add. I fully agree with that (though running unit tests on a single unit of code is very quick). > Meanwhile, the integration tests are used for overall sanity testing. Sure. But in my experience: most codebases have little to no integration tests, and they cover things like "make sure login is not broken" or "make sure saving an entry works" as opposed to "make sure login does not break with the login 'null'" or "make sure we reject an entry which contains invalid XML", because the cost of setting up scenarios is much higher than with integration tests.