popcorn: introduce pop_tests module
authorAlexandre Terrasa <alexandre@moz-code.org>
Thu, 2 Jun 2016 05:35:24 +0000 (01:35 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Thu, 2 Jun 2016 16:03:20 +0000 (12:03 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

lib/popcorn/pop_tests.nit [new file with mode: 0644]

diff --git a/lib/popcorn/pop_tests.nit b/lib/popcorn/pop_tests.nit
new file mode 100644 (file)
index 0000000..1deaeab
--- /dev/null
@@ -0,0 +1,162 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Popcorn testing services
+#
+# ## Blackbox testing
+#
+# Popcorn allows you to test your apps using nitunit blackbox testing.
+#
+# With blackbox testing you compare the output of your program with a result file.
+#
+# To get started with blackbox testing, create a nitunit test suite and imports
+# the `pop_tests` module.
+#
+# You then need to build the app that will be tested by nitunit as shown in the
+# `test_example_hello` method.
+# Calling `run_test` will automatically set the `host` and `port` used for testing.
+#
+# Redefine the `client_test` method to write your scenario.
+# Here we use `curl` to access some URI on the app.
+#
+# ~~~nitish
+# module test_example_hello is test_suite
+#
+# import pop_tests
+# import example_hello
+#
+# class TestExampleHello
+#      super TestPopcorn
+#
+#      fun test_example_hello do
+#              var app = new App
+#              app.use("/", new HelloHandler)
+#              run_test(app)
+#      end
+#
+#      redef fun client_test do
+#              system "curl -s {host}:{port}"
+#              system "curl -s {host}:{port}/"
+#              system "curl -s {host}:{port}///////////"
+#              system "curl -s {host}:{port}/not_found"
+#              system "curl -s {host}:{port}/not_found/not_found"
+#      end
+# end
+# ~~~
+#
+# The blackbox testing needs a reference result file against wich the test output
+# will be compared.
+# Create your expected result file in `test_example_hello.sav/test_example_hello.res`.
+#
+# Test your app by running nitunit:
+#
+# ~~~bash
+# nitunit ./example_hello.nit
+# ~~~
+#
+# See `examples/hello_world` for the complete example.
+module pop_tests
+
+import test_suite
+import popcorn
+import pthreads
+
+redef class Sys
+
+       # Use localhost for testing
+       var test_host = "localhost"
+
+       # Return a new port for each instance
+       fun test_port: Int do
+               srand
+               return 10000+20000.rand
+       end
+end
+
+# Thread running the App to test.
+class AppThread
+       super Thread
+
+       # Host used by tested App.
+       var host: String
+
+       # Port used by tested App.
+       var port: Int
+
+       # App to test.
+       var app: App
+
+       redef fun main
+       do
+               # Hide testing concept to force nitcorn to actually run
+               "NIT_TESTING".setenv("false")
+               app.quiet = true
+               app.listen(host, port)
+               return null
+       end
+end
+
+# Thread running the test client.
+class ClientThread
+       super Thread
+
+       # Test suite to execute.
+       var test_suite: TestPopcorn
+
+       redef fun main do
+               test_suite.client_test
+               print ""
+               return null
+       end
+end
+
+# TestSuite for Popcorn blackbox testing.
+class TestPopcorn
+       super TestSuite
+
+       # Host used to run App.
+       var host: String = test_host
+
+       # Port used to run App.
+       var port: Int = test_port
+
+       # Run the test suite on the App.
+       fun run_test(app: App) do
+               var server = new AppThread(host, port, app)
+               server.start
+               0.1.sleep
+
+               var client = new ClientThread(self)
+               client.start
+               client.join
+               0.1.sleep
+
+               exit 0
+       end
+
+       # Redefine this method to implement your test scenario.
+       fun client_test do end
+
+       # Regex to catch and hide the port from the output to get consistent results
+       var host_re: Regex = "localhost:\[0-9\]+".to_re
+
+       # Execute a System function.
+       fun system(cmd: String, title: nullable String)
+       do
+               title = title or else cmd
+               title = title.replace(host_re, "localhost:*****")
+               print "\n[Client] {title}"
+               sys.system cmd
+       end
+end