cucumber-scala and Play Framework integration testing - scala

I've managed to get cucumber-scala up and running on a Play/Scala. Now I want to run the entire play application so that I can use something like Selenium to test my application.
My Current attempts have lead me to
val app = new FakeApplication()
val port = 3333
lazy val browser: TestBrowser = TestBrowser.of(webDriverClass, Some("http://localhost:" + port))
lazy val server = TestServer(port, app)
Of course this FakeApplication() is not configured in any way... Am I approaching this incorrectly? This application is also multi-module and Ideally I would like to have the feature tests run per module (see output from tree below)
├── README.md
├── build.sbt
├── conf
│   ├── application.conf
│   └── routes
├── logs
│   └── application.log
├── modules
│   ├── module1
│   │   ├── app
│   │   ├── conf
│   │   ├── target
│   │   └── test
│   └── module2
│   ├── app
│   ├── conf
│   └── target
└── project
   ├── build.properties
   ├── plugins.sbt
   ├── project
   │   └── target
   └── target
   ├── config-classes
   ├── resolution-cache
   ├── scala-2.10
   └── streams
I am aware that Play has a selenium integration which can be used to drive my tests. However I have a business requirement for feature files, as they are used as a reporting mechanism. I am not absolutely tied to Cucumber so if anyone is aware of a way of driving browser based tests using Feature files that would also be acceptable to me?
Thanks,
Ben
Update:
I was running through IntelliJ, which causes a server to run with no routes or anything provided. I assume this is because it runs with a default blank application.
However When running through sbt test I get the following output:
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:
1) Error in custom provider, Configuration error: Configuration error[Router not found: admin.Routes]
while locating play.api.inject.guice.FakeRouterProvider
while locating play.api.routing.Router
for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
while locating play.api.http.JavaCompatibleHttpRequestHandler
while locating play.api.http.HttpRequestHandler
for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:221)
at play.api.DefaultApplication.class(Application.scala:221)
while locating play.api.DefaultApplication
while locating play.api.Application

If you're using the default configuration settings for IntegrationTest in sbt, and ScalaTestPlusPlay, here are the directories to use:
src/it/scala – scala IT code
src/it/java – java IT code
src/it/resources – resources, including configuration
Place your application.conf and routes files in the resources directory and FakeApplication will pick it up. You can also set the paths in your sbt script to some other place.
If all of your development/integration testing machines are Unix-like and you use git for VC, you can use a relative symlink1 to your real routes file.
For Windows or other VCS's, you'll likely have to copy the routes file and do double maintenance.
1 symlink using a relative path to the original, e.g., ../../../conf/routes.

Related

Cannot load resource files using Scala / Mill

I cannot load resources in Scala, using Mill (0.10.5) as the build tool.
The minimal example is:
.
├── app
│   └── src
│   └── main
│   ├── resources
│   │   └── hello_world.txt
│   └── scala
│   └── Main.scala
├── build.sc
└── out
with build.sc:
import mill._, scalalib._, mill.modules.Jvm
object app extends ScalaModule {
def scalaVersion = "2.13.5"
}
and Main.scala:
import scala.io.Source
object Main {
def main(args: Array[String]): Unit = {
val helloWorldText : Iterator[String] = Source.fromResource("/hello_world.txt").getLines
helloWorldText.foreach(println)
}
}
While mill -i app.run compiles, the program throws an exception:
Exception in thread "main" java.io.FileNotFoundException: resource 'hello_world.txt' was not found in the classpath from the given classloader
What is the right approach to access resource files using Mill?
Mill ScalaModule does not use the Maven/SBT directory layout by default. Instead, it expects the following directory structure:
.
├── app
│ ├── src
│ | └── Main.scala
│ └── resources
| └── hello_world.txt
├── build.sc
└── out
This is also part of the Getting Started section in the documentation.
What you are looking for is a SBT-compatible project layout, which is discussed in the documentation under section SBT-compatible Modules. In short, you need to extend from SbtModule instead of ScalaModule.
Alternatively, you can also override the sources and resources targets, to customize to your needs.

Bitbake hello world example fails

I'm following this tutorial:
https://docs.yoctoproject.org/bitbake/bitbake-user-manual/bitbake-user-manual-hello.html
My bitbake version is 1.50.0 and BBPATH is following:
export BBPATH="/home/testusr/projects/bitbake_example/bitbake_sample_project/hello"
and I'm at the last step of the tutorial with following file structure:
/home/testusr/projects/bitbake_example/bitbake_sample_project $ tree
.
├── hello
│   ├── classes
│   │   └── base.bbclass
│   └── conf
│   ├── bblayers.conf
│   └── bitbake.conf
└── mylayer
├── conf
│   └── layer.conf
└── printhello.bb
The problem is when I try to build that:
/home/testusr/projects/bitbake_example/bitbake_sample_project/hello $ bitbake printhello
WARNING: Layer mylayer should set LAYERSERIES_COMPAT_mylayer in its conf/layer.conf file to list the core layer names it is compatible with.
Loading cache: 100% | | ETA: --:--:--
Loaded 0 entries from dependency cache.
WARNING: No bb files in default matched BBFILE_PATTERN_mylayer '^\/home\/testusr\/projects\/bitbake_example\/bitbake_sample_project\/mylayer/'
ERROR: Nothing PROVIDES 'printhello'
The warning is saying that there are no bb files under:
/home/testusr/projects/bitbake_example/bitbake_sample_project/mylayer/
but this file is clearly there as can be seen in tree output, so I'm totally confused.
The problem was with the tutorial in layer.conf file. It had:
BBFILES += "${LAYERDIR}/\*.bb"
Instead of:
BBFILES += "${LAYERDIR}/*.bb"
and that's why it couldn't be found.

How can I make test data files accessible to pytest tests when run with tox?

I want to run a test for a function which accepts a Path to a file as input via an argument: function(some_path_to_file) via tox. The file I want to pass to the function cannot be created temporarily during test setup (what I usually do via pytests builtin tmpdir fixtures) but resides in the package <package>/data directory besides the test directory <package>/tests (the location <package>/tests/data would probably be better). Because tox runs the tests in a virtualenv it's not clear to me how to make the test data file available to the test. I know that I can define the base temporary directory of pytest with the --basedir option but I did not get it working with tox yet.
tl;dr
The problem was a conversion of some_path_to_file from Path to str (to pass it to sqlite3.connect(database inside the function) using Path.resolve(. No need to configure pytests --basedir option and tox in any way.
This tripped me up as well. The way I was able to solve it was to specify the full path of the text file I wanted the testing function to read relative to the base directory.
So for example, my directory tree looks like this:
.
├── __init__.py
├── my_package
│   ├── __init__.py
│   └── calculate_stats.py
├── my_package.egg-info
│   ├── PKG-INFO
│   ├── SOURCES.txt
│   ├── dependency_links.txt
│   ├── requires.txt
│   └── top_level.txt
├── bin
│   └── calculate_stats
├── requirements
│   ├── default.txt
│   └── development.txt
├── setup.py
├── test
│   ├── __init__.py
│   ├── test_calculate_stats.csv
│   ├── test_calculate_stats.txt
│   └── test_calculate_stats.py
└── tox.ini
In the file test_calculate_stats.py I have the following line:
assert (calculate_stats.calculate_stats_to_csv("test/test_calculate_stats.txt", "test/test_calculate_stats.csv") == 60)
The calculate_stats_to_csv function reads in the test/test_calculate_stats.txt file, calculates some stats, and outputs them to test/test_calculate_stats.csv
Initially I had just specified the input file to be test_calculate_stats.txt because it's in the same directory as the file containing the testing function -- that's when I ran into the error.
tox predfines a number of substitutions. The directory of the virtualenv is {envdir}, site-packages is at {envsitepackagesdir}. Pass a value from the command line to your test script like this:
[testenv]
commands = pytest --basedir={envsitepackagesdir}/mypackage

SBT: Exclude resource subdirectory

I've been using Gradle for most of my Scala projects, but I want to evaluate the suitability of SBT as a replacement. One of the things I've done in Gradle is to exclude a certain resource directory from the final build (for example, using CoffeeScript to write JavaScript files that will be included as final resources).
In Gradle, I'd do this by:
sourceSets {
main {
resources {
exclude 'com/example/export/dev' // exclude development resources
}
}
}
And this would exclude the resource package com.example.export.dev package from the final build.
How would I do the same in SBT? I've tried
unmanagedResourceDirectories in Compile -= (resourceDirectory in Compile).value / "com/example/export/dev"
but that doesn't do a thing (I understand why, but that doesn't really help). And the documentation on the SBT web site only talks about excluding file patterns (at Classpaths, sources, and resources).
As a more descriptive image, say we have the following resource directory structure:
com
\---example
\---export
\---dev
\---something
In the final output, I want:
com
\---example
\---export
\---something
The way to think in SBT is a bit different and I know it can be hard at first.
In your example, you need to modify the task that generate the resource files (or the task that selects the folders to look for resource files).
Here is an example of how I can select only the resource files that start with character 'a'.
(unmanagedResources in Compile) := (unmanagedResources in Compile).value.filter(_.getName.startsWith("a"))
Similarly if you want to modify the entire directory of the resource files you can do that like this:
(unmanagedResourceDirectories in Compile) := (unmanagedResourceDirectories in Compile).value.filter(_.getName.startsWith("a"))
Obviously my filters here are just and example, you can have any complex pattern that Scala supports.
The nice thing about SBT is that it's interactive. So you can check the result of your task by simply typing these at the REPL of your project:
> show compile:unmanagedResources
> show compile: unmanagedResourceDirectories
To check all the dependencies to the task do this from the REPL:
> inspect tree compile:unmanagedResources
Assumption:
SBT knows where to find all resources using the standard maven build directory layout. The above solution assumes that all resources are under the /resources directory. You can then access them from your Scala code using getClass.getResource("/folderInsideResources/file.txt").
Here is a sample directory layout for a mixed Java/Scala project with resources:
.
├── main
│   ├── java
│   │   └── com
│   │   └── a
│   │   └── b
│   │   └── Hello.java
│   ├── resources
│   │   ├── a.tx
│   │   └── b.tx
│   └── scala
│   └── com
│   └── a
│   └── b
│   └── ScalaHello.scala
└── test
├── resources
└── scala
└── com
└── a
└── b
└── ScalaHello.scala
To access the resource file just use:
getClass.getResource("/a.txt")
getClass.getResource("/b.txt")
From https://github.com/sbt/sbt-jshint/issues/14:
excludeFilter in unmanagedResources := {
val public = ((resourceDirectory in Compile).value / "com" / "example" / "export" / "dev").getCanonicalPath
new SimpleFileFilter(_.getCanonicalPath startsWith public)
}

Scala home directory for creating Scala project in IntelliJ IDEA

I'm new to both Scala and IntelliJ. I've installed Scala plugin for IntelliJ
I've installed Scala in my Ubuntu system with
sudo apt-get install scala
When I try to create new scala project, I'm required to do Scala Settings.
But the problem is I couldn't find the the home directory for my Scala installation.
What is the home directory for Scala in my ubuntu?
Thanks.
The plugin wants to know where the Scala libraries are installed (as it would want to know where the Java SDK is located for a Java module). Note that for different Scala projects you might use different versions of Scala: 2.9.0 or 2.10.2, etc. The dialog offers to download them or you can go to the Scala site and download them yourself. For example, I downloaded scala-2.10.2.tgz from http://www.scala-lang.org/download/ and expanded it in /home/glenn/Applications/Scala/ to
/home/glenn/Applications/Scala/scala-2.10.2/. This latter path is what goes in the "Set Scala Home" field in the dialog.
Note that in my case this is preferable to using the apt-get installation of Scala because the API changes so much that I usually end up with different versions of Scala for different projects that I experiment with.
Follow the version links at http://www.scala-lang.org/download/all.html to the version page with the download for the docs.
Note that for me, IDEA wanted the docs to be in the "doc/scala-devel-docs" directory, whereas the downloaded docs decompressed to "scala-docs-2.10.2". I made a link so that IDEA can find them. My 2.10.2 directory looks like this, now.
scala-2.10.2
├── bin
├── doc
│   ├── scala-devel-docs -> scala-docs-2.10.2
│   ├── scaladoc
│   │   └── lib
│   ├── scala-docs-2.10.2
│   │   └── api
│   └── tools
│   ├── css
│   └── images
├── examples
│   ├── actors
│   ├── monads
│   ├── parsing
│   │   └── lambda
│   ├── tcpoly
│   │   └── monads
│   └── xml
│   └── phonebook
├── lib
├── man
│   └── man1
├── misc
│   └── scala-devel
│   └── plugins
└── src
Run
$ dpkg -L scala
It will show a list of files in that package. Search for scalac:
$ dpkg -L scala | grep scalac
It will be something like /usr/share/scala/bin/scalac. Strip off /bin/scalac part and you will get Scala home: /usr/share/scala.
Update
It seems that there is no dedicated Scala home in Ubuntu. scala-library package files are installed simply to /usr/share/java. I guess then that the most simple way to get proper Scala home is to download a tarball from http://scala-lang.org/, extract it somewhere and use extracted directory as Scala home.