7

Since it is convenient for the developer, the same paradigm are often used for implementations and specifications, e.g.

  • for testing (e.g. Java for the implementation and unit tests, Scala for the implementation and property testing)
  • for model-based testing (e.g. C# for the implementation and specifications using Spec Explorer, or Java for the implementation and specifications using Conformiq)
  • for verification (e.g. C for some embedded software and specifications in the C-like language Promela for model checking, or Dafny, which integrates implementation and specification).

There even seems to be a trend in this direction.

I always thought using different paradigms would help think on different abstraction levels and more generally in different structures, and that faults could be detected much better that way, when checking the implementation against the tests/specification (similar to using design diversity for fault tolerant systems).

So is it true that different paradigms for the implementation and specification can avoid more faults? Do you have a citable reference?

5
  • 1
    If you're suggesting using a functional language to write the unit tests for an app written in an imperative/OOP language, or vice versa, honestly I'm not even sure if it's feasible to do that, much less beneficial. Every single test would involve at least some wrangling with a foreign function interface, and some of the properties or behaviors you'd want to test may simply not be possible in one or the other language (eg, mutability). Are you thinking primarily about acceptance or integration testing? Is there any specific reason you think it would be a good thing?
    – Ixrec
    Commented Jul 11, 2015 at 14:21
  • 1
    Yes, using functional languages for the tests/specification and not for the implementation is a great example of what I'm thinking about. And there are examples of this use, in contract-based runtime verification.I do believe it is better since you can formulate functionality completely differently, avoiding to make the same mistakes in the implementation and in the specification. For tests/specifications that are more general than specification by example, I have often seen the logic from the implementation reimplemented in the tests/specification, which cries for switching the paradigm.
    – DaveFar
    Commented Jul 11, 2015 at 15:16
  • 1
    See Cucumber or SpecFlow for a TDD language that is not based on your application language. Is this more like that you mean?
    – gbjbaanb
    Commented Jul 27, 2015 at 20:45
  • @gbjbaanb: Good idea. Do you know of some case study where the reduction of faults due to the paradigm switch is measured? I guess it will be difficult to differentiate whether the number of faults is reduced because a different paradigm is used or because BDD is a ubiquitous language...
    – DaveFar
    Commented Jul 27, 2015 at 21:15
  • in clean code series around the #28 Finite State Machines and The State Pattern there is a mention about switching Your view with a different model. For example You start TDD implementing every kind of features You want. But later You switch the paradigm, to model a state machine for Yourself, to be able to visualize which feature should be enabled on the UI in terms of where You are.
    – ntohl
    Commented Jul 30, 2015 at 8:24

3 Answers 3

1
+50

This is not completely related, but if you includes formal specification languages, you have benefits with annotating your code with formal invariants and contracts.

See for example the ACSL reference manual, for C. The same goes for Ada which allows forall expressions that are not part of the language, but available for specifications: http://docs.adacore.com/spark2014-docs/html/ug/appendix.html. Also, you could have a look at ACL2.

When it comes to tests, you may want to look at Model-Based Testing: you define a model that is useful only for tests.

It is often easier to describe the test in a functional way clearly conveys what the implementation should do, instead of how.

2
  • It is exactly in those fields that I have seen the logic of the implementation replicated into the specification. So the probability that a fault in the implementation is also replicated in the specification and hence not detected is high. Using different constructs, as quantifiers, helps reduce such replication, which is the motivation for my question.
    – DaveFar
    Commented Jul 13, 2015 at 17:42
  • 1
    @DaveFar I have seen it too: specifications parroting what the implementation does. Also, sometimes, specifications assert the obvious but fail to describe more important relationships: for example one define a comparison function and specify what the order is but fail to state whether it is supposed to be total or partial. The approach should help, in principle, but may fail to be applied successively.
    – coredump
    Commented Jul 13, 2015 at 18:17
1

I think what you want is some level of formalism, see Formal Methods. This is the only guaranteed way to get less fault by using different paradigms because just using something different also has the potential to give different faults (even fixes produce bugs).

Doing implementation in level closer to math will give the ability to have some level of mathematical proof, which means you will have no fault and potentially eliminate need for testing.

This link From HOL to Haskell and Software Foundations should illustrate ideas of using developing specification in theorem prover then translate it into programming language. One article talks about using Isabelle/HOL and haskell, the other is about using Coq, which then you can translate into scala using some tool.

Because it takes more time to do it formally, only small amount of code are developed this way.

2
  • With formal methods you seem to have a fairly large probability of faults when "translating specs into maths", so it's not infallible either. And the wider disconnect might mean those faults are more likely, even if other kinds of faults are less likely. Commented Jul 31, 2015 at 6:20
  • @immibis We have two kinds of faults, ones in design ("translating specs") and ones in implementation (which there should be eliminated). The translating itself should reveal faults in the specs, because to be able to translate specs into provable theorems, the specs have to be valid in the first place, or you can't prove them. So, it's more likely that the specs will need to be fixed. Then at the end of the process, the specs will be valid. Even if we decided to implement this final specs in a different implementation (non-proven implement), the end result should still be better.
    – imel96
    Commented Aug 3, 2015 at 1:15
0

It's my opinion as a QA person that one doesn't really need different testing paradigims. Many will disagree with this statement but there's only one method necessary which is simply testing all known edge cases of whatever it is. The theory is simply Min, Min-1, Min+1, Max, Max-1 and Max+1, Null and or Empty String. If every one of those edges are tested you have bullet proof code.

People will say nonsense and use fancy terms like end-to-end, black box, white box, grey box, unit test, user acceptance test, unit testing, integration, component and system testing, they'll talk about randomness, statistical approaches. etc. All of the above boils down to Edge cases as the method to use. Edge case tests can be run manually, automated etc.

Finally studies show >70% of all bugs are introduced prior to the developer delivering code to QA. What does this mean? It means the best effort for automation is Unit Test! Now consider this, 90% of all developers say "Unit Testing is not built-in to my schedule"... Result is that non-bullet-proof code is continually being delivered to QA, but QA can only catch maybe 20-50% of all bugs as they can't see the code usually...

Writing test cases in the language the developers use is good because now the developers can contribute and maintain the Unit Test library. QA folks should embed with developers and write tests as the code is being created. Test Stubs can be written just from a specification and make the test almost ready for when code is there.

It is true that developers simply don't have the proper time to develop good Unit Tests given today's fast schedules.

1
  • 1
    I believe the question is asking about e.g. functional tests for object-oriented code, or vice versa. Commented Jul 31, 2015 at 6:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.