diff --git a/tests/main.cpp b/tests/main.cpp
new file mode 100644
index 000000000..b6383f019
--- /dev/null
+++ b/tests/main.cpp
@@ -0,0 +1,43 @@
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name main.cpp - The main file for unittest. */
+//
+//      (c) Copyright 2013 by Joris Dauphin
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; only version 2 of the License.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+#include <UnitTest++.h>
+#include <TestReporterStdout.h>
+
+
+int main(int argc, char* argv[])
+{
+#if 0
+	UnitTest::TestReporterStdout reporter;
+
+	return UnitTest::RunAllTests(reporter, UnitTest::Test::GetTestList(), "TESTME");
+#else
+	return UnitTest::RunAllTests();
+#endif
+}
diff --git a/tests/network/test_net_lowlevel.cpp b/tests/network/test_net_lowlevel.cpp
new file mode 100644
index 000000000..823fa8ff2
--- /dev/null
+++ b/tests/network/test_net_lowlevel.cpp
@@ -0,0 +1,306 @@
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name test_net_lowlevel.cpp - The test file for net_lowlevel.cpp. */
+//
+//      (c) Copyright 2013 by Joris Dauphin
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; only version 2 of the License.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+#include <UnitTest++.h>
+
+#include "stratagus.h"
+#include "net_lowlevel.h"
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+class AutoNetwork
+{
+public:
+	AutoNetwork() { NetInit(); }
+	~AutoNetwork() { NetExit(); }
+};
+
+TEST_FIXTURE(AutoNetwork, NetResolveHost)
+{
+	const unsigned long localhost = ntohl(0x7F000001); // 127.0.0.1
+
+	CHECK_EQUAL(localhost, NetResolveHost("127.0.0.1"));
+	CHECK_EQUAL(localhost, NetResolveHost("localhost"));
+}
+
+class Job
+{
+public:
+	virtual ~Job() {}
+
+	void Run() { pthread_create(&tid, NULL, Job::ThreadRun, this); }
+	void Wait() { pthread_join(tid, NULL); }
+
+private:
+	virtual void DoJob() = 0;
+
+	static void *ThreadRun(void *data)
+	{
+		Job *that = reinterpret_cast<Job*>(data);
+		that->DoJob();
+		return NULL;
+	}
+
+private:
+	pthread_t tid;
+};
+
+template<typename T>
+void TCPWrite(Socket socket, const T &obj)
+{
+	T dup(obj);
+
+	const char *buf = reinterpret_cast<const char *>(&dup);
+	size_t s = 0;
+	while (s != sizeof(T)) {
+		s += NetSendTCP(socket, buf + s, sizeof(T) - s);
+	}
+}
+
+template<typename T>
+void TCPRead(Socket socket, T *obj)
+{
+	char *buf = reinterpret_cast<char *>(obj);
+	size_t s = 0;
+	while (s != sizeof(T)) {
+		s += NetRecvTCP(socket, buf + s, sizeof(T) - s);
+	}
+}
+
+class ServerTCP
+{
+public:
+	explicit ServerTCP(int port) { socket = NetOpenTCP(NULL, port); }
+	~ServerTCP() { NetCloseTCP(socket); }
+
+	bool Listen() { return NetListenTCP(socket) != -1; }
+	void Accept() { clientSocket = NetAcceptTCP(socket); }
+
+	template <typename T>
+	void Write(const T &obj) { TCPWrite(clientSocket, obj); }
+
+private:
+	Socket socket;
+	Socket clientSocket;
+};
+
+class ClientTCP
+{
+public:
+	explicit ClientTCP(int port) { socket = NetOpenTCP(NULL, port); }
+	~ClientTCP() { NetCloseTCP(socket); }
+
+	bool Connect(const char *host, int port) { return NetConnectTCP(socket, NetResolveHost(host), port) != -1; }
+
+	template <typename T>
+	void Read(T *obj) { TCPRead(socket, obj); }
+
+private:
+	Socket socket;
+};
+
+class Foo
+{
+public:
+	Foo() { memset(&data, 0, sizeof(data)); }
+
+	void Fill()
+	{
+		for (int i = 0; i != 42; ++i) {
+			data[i] = i;
+		}
+	}
+
+	bool Check() const
+	{
+		for (int i = 0; i != 42; ++i) {
+			if (data[i] != i) {
+				return false;
+			}
+		}
+		return true;
+	}
+public:
+	char data[42];
+};
+
+class ReceiverTCPJob : public Job
+{
+public:
+	explicit ReceiverTCPJob(ClientTCP& client) : client(&client), check(false) {}
+
+	bool Check() const { return check; }
+private:
+
+	virtual void DoJob()
+	{
+		Foo foo;
+
+		client->Read(&foo);
+		check = foo.Check();
+	}
+private:
+	ClientTCP *client;
+	bool check;
+};
+
+class SenderTCPJob : public Job
+{
+public:
+	explicit SenderTCPJob(ServerTCP& server) : server(&server) {}
+
+private:
+	virtual void DoJob()
+	{
+		server->Listen();
+		server->Accept();
+
+		Foo foo;
+
+		foo.Fill();
+		server->Write(foo);
+	}
+private:
+	ServerTCP *server;
+};
+
+TEST_FIXTURE(AutoNetwork, ExchangeTCP)
+{
+	ServerTCP server(6500);
+	SenderTCPJob sender(server);
+	sender.Run();
+
+	ClientTCP client(6501);
+	client.Connect("localhost", 6500);
+	ReceiverTCPJob receiver(client);
+	receiver.Run();
+
+	receiver.Wait();
+	sender.Wait();
+	CHECK(receiver.Check());
+}
+
+template<typename T>
+void UDPWrite(Socket socket, const char *hostname, int port, const T &obj)
+{
+	T dup(obj);
+
+	const long host = NetResolveHost(hostname);
+	const char *buf = reinterpret_cast<const char *>(&dup);
+	port = htons(port);
+	size_t s = 0;
+	while (s != sizeof(T)) {
+		s += NetSendUDP(socket, host, port, buf + s, sizeof(T) - s);
+	}
+}
+
+template<typename T>
+void UDPRead(Socket socket, T *obj)
+{
+	char *buf = reinterpret_cast<char *>(obj);
+	size_t s = 0;
+	while (s != sizeof(T)) {
+		s += NetRecvUDP(socket, buf + s, sizeof(T) - s);
+	}
+}
+
+class ClientUDP
+{
+public:
+	explicit ClientUDP(int port) { socket = NetOpenUDP(NULL, port); }
+	~ClientUDP() { NetCloseUDP(socket); }
+
+	template <typename T>
+	void Read(T *obj) { UDPRead(socket, obj); }
+
+	template <typename T>
+	void Write(const char *hostname, long port, const T &obj) { UDPWrite(socket, hostname, port, obj); }
+
+private:
+	Socket socket;
+};
+
+class ReceiverUDPJob : public Job
+{
+public:
+	explicit ReceiverUDPJob(ClientUDP& client) : client(&client), check(false) {}
+
+	bool Check() const { return check; }
+private:
+
+	virtual void DoJob()
+	{
+		Foo foo;
+
+		client->Read(&foo);
+		check = foo.Check();
+	}
+private:
+	ClientUDP *client;
+	bool check;
+};
+
+class SenderUDPJob : public Job
+{
+public:
+	explicit SenderUDPJob(ClientUDP& client, const char *hostname, int port) :
+		client(&client),
+		hostname(hostname),
+		port(port)
+	{}
+
+private:
+	virtual void DoJob()
+	{
+		Foo foo;
+
+		foo.Fill();
+		client->Write(hostname, port, foo);
+	}
+private:
+	ClientUDP *client;
+	const char *hostname;
+	long port;
+};
+
+TEST_FIXTURE(AutoNetwork, ExchangeUDP)
+{
+	ClientUDP client(6501);
+	ReceiverUDPJob receiver(client);
+	receiver.Run();
+
+	ClientUDP server(6500);
+	SenderUDPJob sender(server, "localhost", 6501);
+	sender.Run();
+
+	receiver.Wait();
+	sender.Wait();
+	CHECK(receiver.Check());
+}
diff --git a/tests/stratagus/test_translate.cpp b/tests/stratagus/test_translate.cpp
new file mode 100644
index 000000000..f58247f0f
--- /dev/null
+++ b/tests/stratagus/test_translate.cpp
@@ -0,0 +1,49 @@
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name test_translate.cpp - The test file for translate.cpp. */
+//
+//      (c) Copyright 2013 by Joris Dauphin
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; only version 2 of the License.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+#include <UnitTest++.h>
+
+#include "stratagus.h"
+#include "translate.h"
+
+TEST(TRANSLATION)
+{
+	const char *originWord = "origin word";
+	const char *translatedWord = "translated word";
+	AddTranslation(originWord, translatedWord);
+
+	CHECK_EQUAL(translatedWord, Translate(originWord));
+	const char *notFound = "not found";
+
+	CHECK_EQUAL(notFound, Translate(notFound));
+
+	CHECK_EQUAL(translatedWord, _(originWord));
+	CHECK_EQUAL(originWord, N_(originWord));
+	// TODO: Remove translation
+}
diff --git a/tests/stratagus/test_util.cpp b/tests/stratagus/test_util.cpp
new file mode 100644
index 000000000..6017dca23
--- /dev/null
+++ b/tests/stratagus/test_util.cpp
@@ -0,0 +1,122 @@
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name test_util.cpp - The test file for util.cpp. */
+//
+//      (c) Copyright 2013 by Joris Dauphin
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; only version 2 of the License.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+#include <UnitTest++.h>
+
+#include "stratagus.h"
+#include "util.h"
+
+TEST(SQUARE)
+{
+	CHECK_EQUAL(4, square(2));
+	CHECK_EQUAL(0, square(0));
+	CHECK_EQUAL(36, square(6));
+}
+
+TEST(CLAMP_MAX)
+{
+	int x = 42;
+
+	clamp(&x, 0, 10);
+	CHECK_EQUAL(10, x);
+}
+
+TEST(CLAMP_MIN)
+{
+	int x = -42;
+
+	clamp(&x, 0, 10);
+	CHECK_EQUAL(0, x);
+}
+
+TEST(CLAMP_IN)
+{
+	int x = 4;
+
+	clamp(&x, 0, 10);
+	CHECK_EQUAL(4, x);
+}
+
+TEST(STRCPY_S)
+{
+	char buffer[42];
+
+	CHECK_EQUAL(EINVAL, strcpy_s(NULL, 42, "NULL dest"));
+	CHECK_EQUAL(EINVAL, strcpy_s(buffer, 42, NULL));
+	CHECK_EQUAL(ERANGE, strcpy_s(buffer, 10, "longer than given size"));
+	CHECK_EQUAL(0, strcpy_s(buffer, 10, "correct"));
+	CHECK_EQUAL("correct", buffer);
+}
+
+TEST(STRNCPY_S)
+{
+	char buffer[42];
+
+	CHECK_EQUAL(EINVAL, strncpy_s(NULL, 42, "NULL dest", 5));
+	CHECK_EQUAL(EINVAL, strncpy_s(buffer, 42, NULL, 5));
+	CHECK_EQUAL(EINVAL, strncpy_s(buffer, 10, "longer than given size", 12));
+	CHECK_EQUAL(0, strncpy_s(buffer, 10, "correct", 8));
+	CHECK_EQUAL("correct", buffer);
+}
+
+TEST(STRCAT_S)
+{
+	char buffer[42];
+
+	buffer[0] = '\0';
+
+	CHECK_EQUAL(EINVAL, strcat_s(NULL, 42, "NULL dest"));
+	CHECK_EQUAL(EINVAL, strcat_s(buffer, 42, NULL));
+	CHECK_EQUAL(ERANGE, strcat_s(buffer, 10, "longer than given size"));
+	CHECK_EQUAL(0, strcat_s(buffer, 42, "hello"));
+	CHECK_EQUAL(0, strcat_s(buffer, 42, " world"));
+	CHECK_EQUAL("hello world", buffer);
+}
+
+TEST(STRCASESTR)
+{
+	const char *text = "HELLO world";
+
+	CHECK(NULL == strcasestr(text, "not found"));
+	CHECK(text == strcasestr(text, "HelLo"));
+	CHECK(text + 6 == strcasestr(text, "WoRlD"));
+	CHECK(text + 4 == strcasestr(text, "o"));
+}
+
+TEST(STRNLEN)
+{
+	CHECK_EQUAL(2u, strnlen("hello", 2));
+	CHECK_EQUAL(5u, strnlen("hello", 5));
+	CHECK_EQUAL(5u, strnlen("hello", 10));
+}
+
+// TODO: int getopt(int argc, char *const argv[], const char *optstring);
+// TODO: int GetClipboard(std::string &str);
+// TODO: int UTF8GetNext(const std::string &text, int curpos);
+// TODO: int UTF8GetPrev(const std::string &text, int curpos);