Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-24 Thread Heinrich Apfelmus

Simon Hengel wrote:

On Sun, Sep 23, 2012 at 06:11:59PM +0200, Heinrich Apfelmus wrote:


How do I access internal modules with  cabal test , though? Last
time I tried, I could not find a way to expose in the test section
of the cabal file.


It works, if you add the source directory to hs-source-dirs of the test
suite (in contrast to depending on the library!), e.g.:

  hs-source-dirs: test, src

or

  hs-source-dirs: test, .

This still has the disadvantage, that the sources are compiled twice.
But I'm not aware of a better way to do it.  If you mostly use GHCi for
development, it's not a big issue.


I got it to work, thanks!

I also had to duplicate the dependency information, but that's alright.


Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Jan Stolarek
Dear list,

during many years of Java programming I've been faithful to TDD methology. 
Recently I've been 
trying to figure out how to do tests in Haskell. Thanks to RWH and help from 
great folks at 
#haskell I've managed to get on my feet. There is however one issue I wasn't 
able to solve.

In Java it is very easy to separate test code from the actual source. A Java 
project simply 
contains two folders: src and tests. These two are treated as the source 
directories. Both these 
directories have the same subdirectory structure. For example I have a source 
file 
src/myPackage/mySubpackage/MyClass.java and test for it are kept in file 
tests/myPackage/mySubpackage/MyClassTest.java. These two files are considered 
by Java to be in 
the same package. Here's the main trick: fileds and methods that are marked as 
protected in Java 
are accessible to other classes in the same package. This allows to test 
internal methods of a 
class by marking them as protected instead of private. This breaks 
encapsulation but only within 
a package, which is acceptable.

Now I'd like to achieve something similar in Haskell. I'm using cabal's support 
for testing. I 
created separate src and tests directories, both with the same subdirectory 
structure. I keep 
tests for each module in a separate file (e.g. I have src/Math/MyModule.hs and 
tests/Math/MyModuleTest.hs) and I have one file that assembles all the tests 
into a single test 
suite (I use test-framework for that). The only problem is that in order to 
test some function 
from a module I have to expose that function, which pretty much forces me to 
give up on 
encapsulation.

Is there any better solution to organize tests in Haskell? Should I just give 
up on module 
encapsulation, or should I only test functions exposed by the module and don't 
worry about 
internal functions? Perhaps I should use some different approach?

Jan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Simon Hengel
Hi,

 Is there any better solution to organize tests in Haskell?

(Disclaimer: I'm the maintainer of Hspec ;)

If you use Hspec[1] for testing, you do not have to assemble your
individual tests manually into a test suit; hspec-discover[2] takes care
of that.

There is no comprehensive user's guide for Hspec yet, but a basic
introduction is at [3].  If you have any questions, feel free to join in
at #hspec on freenode.

 Should I just give up on module encapsulation, or should I only test
 functions exposed by the module and don't worry about internal
 functions?

You can do it with CPP.  Say, if you have a module Foo, with functions
foo, bar and baz, where baz  is not part of the public interface, then
the export list becomes:


{-# LANGUAGE CPP #-}
module Foo where (
  foo
, bar
#ifdef TEST
, baz
#endif
)

You then run tests with -DTEST.  To make development easier you can add
a .ghci file to your project, with:

echo ':set -DTEST -isrc -itest'  .ghci

And of course you need to add 

cpp-options: -DTEST

to your Cabal test-suite section.

Cheers,
Simon

[1] http://hackage.haskell.org/package/hspec
[2] 
https://github.com/hspec/hspec/tree/master/hspec-discover#automatically-discover-and-run-hspec-tests
[3] http://hspec.github.com/

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Matthew West

On 23 Sep 2012, at 10:25, Jan Stolarek wrote:

 Dear list,
 
 during many years of Java programming I've been faithful to TDD methology. 
 Recently I've been 
 trying to figure out how to do tests in Haskell. Thanks to RWH and help from 
 great folks at 
 #haskell I've managed to get on my feet. There is however one issue I wasn't 
 able to solve.
 
 In Java it is very easy to separate test code from the actual source. A Java 
 project simply 
 contains two folders: src and tests. These two are treated as the source 
 directories. Both these 
 directories have the same subdirectory structure. For example I have a source 
 file 
 src/myPackage/mySubpackage/MyClass.java and test for it are kept in file 
 tests/myPackage/mySubpackage/MyClassTest.java. These two files are considered 
 by Java to be in 
 the same package. Here's the main trick: fileds and methods that are marked 
 as protected in Java 
 are accessible to other classes in the same package. This allows to test 
 internal methods of a 
 class by marking them as protected instead of private. This breaks 
 encapsulation but only within 
 a package, which is acceptable.
 
 Now I'd like to achieve something similar in Haskell. I'm using cabal's 
 support for testing. I 
 created separate src and tests directories, both with the same subdirectory 
 structure. I keep 
 tests for each module in a separate file (e.g. I have src/Math/MyModule.hs 
 and 
 tests/Math/MyModuleTest.hs) and I have one file that assembles all the tests 
 into a single test 
 suite (I use test-framework for that). The only problem is that in order to 
 test some function 
 from a module I have to expose that function, which pretty much forces me to 
 give up on 
 encapsulation.
 
 Is there any better solution to organize tests in Haskell? Should I just give 
 up on module 
 encapsulation, or should I only test functions exposed by the module and 
 don't worry about 
 internal functions? Perhaps I should use some different approach?
 
 Jan
 
Hi,
  From looking at other packages on Hackage a common trick seems to be to 
create some internal modules, 
then have an external module that simply exposes the 'public' functions.  Your 
internal tests can then import 
the internal modules, and your API tests can import the external module.  Of 
course others are still able to import 
your Internal modules, but you have at least made it clear that that is a bad 
idea.

for example:

MyLib/Internal/Lib.hs:

module MyLib.Internal.Lib where -- exports all the functions defined in this 
function
internalFunction = ...
externalFunction = ...

MyLib/Lib.hs
module MyLib.Lib (   -- exports only the public functions
externalFunction
)
where
import MyLib.Internal.Lib  -- imports all the internal functions

test/Internal/Lib.hs
...
import MyLib.Internal.Lib
...

test/Lib.hs
...
import MyLib.Lib   -- imports only the public API
...

Yesod is an example of a large project using this approach, for example 
https://github.com/yesodweb/yesod/tree/master/yesod-core

Matt


 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Simon Hengel
 Of course others are still able to import your Internal modules

That is not necessarily true.  For libraries, you can list internal
modules as other-modules (in contrast to exposed-modules) in you Cabal
file.  That way they are not part of the public interface of your
library.

However, that approach does not work if you want to do encapsulation
within a single project.  I think in that case you most likely end up
with CPP (it's ugly, but it works).

Cheers,
Simon

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Jan Stolarek
Thanks for replies. CPP approach seems to be what I would like to achieve, but 
it looks more like 
a hack than a real solution. That said, I like the idea of creating a module 
that acts as an 
external interface to the library and I I don't mind sacrificing encapsulation 
within the package 
itself. If it works for project as big as Yesod it should work for me.

 If you use Hspec[1] for testing, you do not have to assemble your
 individual tests manually into a test suit; hspec-discover[2] takes care
 of that.
I guess that I like to have my tests organized manually. It takes a bit of more 
work and there's a 
risk that I forget to add some test to the suite, but I'm willing to accept 
these drawbacks and 
get more fine-grained control in return.

Jan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Heinrich Apfelmus

Simon Hengel wrote:

Of course others are still able to import your Internal modules


That is not necessarily true.  For libraries, you can list internal
modules as other-modules (in contrast to exposed-modules) in you Cabal
file.  That way they are not part of the public interface of your
library.


How do I access internal modules with  cabal test , though? Last time I 
tried, I could not find a way to expose in the test section of the cabal 
file.



Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Simon Hengel
On Sun, Sep 23, 2012 at 06:11:59PM +0200, Heinrich Apfelmus wrote:
 Simon Hengel wrote:
 Of course others are still able to import your Internal modules
 
 That is not necessarily true.  For libraries, you can list internal
 modules as other-modules (in contrast to exposed-modules) in you Cabal
 file.  That way they are not part of the public interface of your
 library.
 
 How do I access internal modules with  cabal test , though? Last
 time I tried, I could not find a way to expose in the test section
 of the cabal file.

It works, if you add the source directory to hs-source-dirs of the test
suite (in contrast to depending on the library!), e.g.:

  hs-source-dirs: test, src

or

  hs-source-dirs: test, .

This still has the disadvantage, that the sources are compiled twice.
But I'm not aware of a better way to do it.  If you mostly use GHCi for
development, it's not a big issue.

Cheers,
Simon

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Organizaing tests in Haskell

2012-09-23 Thread Simon Hengel
On Sun, Sep 23, 2012 at 04:10:56PM +0200, Jan Stolarek wrote:
 I don't mind sacrificing encapsulation within the package itself. If
 it works for project as big as Yesod it should work for me.

Yesod uses the CPP solution, too (e.g. [1]).

Cheers,
Simon

[1] 
https://github.com/yesodweb/shakespeare/blob/master/shakespeare/Text/Shakespeare.hs

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe