How to efficiently unit test the parameters of dynamic languages?

This answer struck me as having never understood with the way you handle parameter types in dynamic languages ​​versus a static language (my perspective is informed or warped - whatever you want) from Java.

Given the foo method, which accepts a string of parameters in a dynamic language, there is no enforcement at compile time of the string type. The answer linked above (and the answer I usually see on this one) is that you need to unit test correctly in a dynamic language.

But at some point, something outside the unit will call this method. Let's say it's heavy weight that will mock any unit tests of the classes that use it. Now you have many classes called this method and you need to change the type. To keep it simple, it used a number, but now requires an alphanumeric, and you need to use a method specifically available for the string, not the object with the new requirement.

How do you change it and know that the calling code will be fixed? Of course, if you just change it, your unit tests will fail, but since you need to change it on purpose, you will supposedly fix your unit tests. How do you know to fix the calling code? I don't just mean how conceptually you know, I mean how you know you've found all the callers and can really say that that's changed.

It would seem that only very comprehensive integration tests will give you this confidence. Did I miss something?

+2


source to share


6 answers


I think you gave a great concrete example of one of the benefits of static typing. Dynamic typing requires you to find all of these call locations yourself. It's not really that hard - just a text search in your code. It's a trade-off: it's comfortable that the compiler can cross-reference your code and make sure everything matches, and also doesn't distract type tags throughout your code.



+2


source


I need 15 characters to post, but the answer is four characters long: grep.



+2


source


  • Protect the code. Make the change backward compatible in the new method. Sending by argument type; CLOS makes this easy.

  • Use the "who's calling" feature of your editor or IDE.

+2


source


This is more a refactoring question than a unit test question.

Parameters are effectively tested by the module, checking all properties and methods that are needed in a particular function are present and return the expected result. This interface is irrelevant.

+1


source


The short answer is just "more unit tests".

The only thing that matters is that the new type also has the required methods. So if it ClassA

has Method1 () that takes a parameter obj

and calls obj#M1()

and obj#M2()

- the only restriction on obj is that it responds to these messages. If you change the implementation to call a method Foo()

that did not previously exist, the tests that fail class A.

Further, if ClassB

called A#Method1()

as part of its functionality, its tests will fail if class B passes an object obj that has the required methods. If B's ​​required behavior is not achieved, its tests should fail, and this should be directed towards the changes needed by B.

+1


source


Developers of dynamic languages ​​must replicate the benefits of static typing, that is, because these tools can automatically find these errors. For the most part, this includes type inference tools. The conclusion itself is quite complex (I'm writing my candidacy for this for PHP), but using the tools isn't very difficult.

There are bug finding tools for:

For PHP, phc can do it with very little work.

In general, when you don't have static typing, you need a tool to take advantage of it.

+1


source







All Articles