I have the following DSL structure:
freeStyleJob {
wrappers {
credentialsBinding {
[
$class:"AmazonWebServicesCredentialsBinding",
accessKeyVariable: "AWS_ACCESS_KEY_ID",
credentialsId: "your-credential-id",
secretKeyVariable: "AWS_SECRET_ACCESS_KEY"
]
}
}
steps {
// ACCESS AWS ENVIRONMENT VARIABLES HERE!
}
}
However, this does not work. What is the correct syntax to do so? For Jenkins pipelines, you can do:
withCredentials([[
$class: "AmazonWebServicesCredentialsBinding",
accessKeyVariable: "AWS_ACCESS_KEY_ID",
credentialsId: "your-credential-id",
secretKeyVariable: "AWS_SECRET_ACCESS_KEY"]]) {
// ACCESS AWS ENVIRONMENT VARIABLES HERE!
}
but this syntax does not work in normal DSL job groovy.
tl;dr how can I export AWS credentials defined by the AmazonWebServicesCredentialsBinding plugin into environment variables in Groovy job DSL? (NOT PIPELINE PLUGIN SYNTAX!)
I found a solution to solve this problem:
wrappers {
credentialsBinding {
amazonWebServicesCredentialsBinding {
accessKeyVariable("AWS_ACCESS_KEY_ID")
secretKeyVariable("AWS_SECRET_ACCESS_KEY")
credentialsId("your-credentials-id")
}
}
}
This will lead to the desired outcome.
I'm not able to re-use Miguel's solution (even with installed aws-credentials plugin), so here is another approach with DSL configure block
configure { project ->
def bindings = project / 'buildWrappers' / 'org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper' / 'bindings'
bindings << 'com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentialsBinding' {
accessKeyVariable("AWS_ACCESS_KEY_ID")
secretKeyVariable("AWS_SECRET_ACCESS_KEY")
credentialsId("credentials-id")
}
}
This is the full detailed answer that #bitbrain did with possible fix for issue reported by #Viacheslav
freeStyleJob {
wrappers {
credentialsBinding {
amazonWebServicesCredentialsBinding {
accessKeyVariable("AWS_ACCESS_KEY_ID")
secretKeyVariable("AWS_SECRET_ACCESS_KEY")
credentialsId("your-credentials-id")
}
}
}
}
Ensure this is on the classpath for compilation:
compile "org.jenkins-ci.plugins:aws-credentials:1.23"
If you have tests running you might also need to add the plugin to the classpath:
testPlugins "org.jenkins-ci.plugins:aws-credentials:1.23"
I believe this is why there are reports of people needing to manually modify the XML to get this to work. Hint: if you can pass the compile stage (or compile in IDE) but not able to compile tests then this is the issue.
I am using simplified version of the project what I ma looking for is a idea of how to do it in Windows Forms
I have a working command line application. It is a simple school assignment program. The main player of this application is a Database class:
database.h
class Database{
public:
Database(string name);
void add(...)
void remove(...)
//and so on more methods and other stuff
}
I can use it in my main.cpp:
include "database.h"
int main(){
Database db("test");
.
.
.
}
Three dots from this simple example represent all the different thing I can do with that database. db object is available in the main scope.
How can I make instance of the Database, available to all the windows in a Windows Form project?
Where/How should I instantiate Database object to be available to all forms?
I would basically like to include my excising database.h file, instantiate the object out of it and be able to use it in different windows in the application.
I am using VS 2010 Ultimate.
I am currently developing on a Chromium Embedded framework app.
The project consists of a client and a helper. I need to know the bundle path from the helper, easy just use the methods of foundation.... Well I can't since I can't use foundation in the helper.
The client is a C++ based core wrapped in a objective-c++ cocoa app.
The helper is pure C++.
The two apps share an custom class for process-type-based behaviour ( see code below). The "OnBeforeCommandLineProcessing" method needs to use the bundle path! (Just changing file ending to .mm and importing foundation/cocoa does not work, as soon as i import foundation things turn ugly with a huge amount of errors). How can I get bundle path from C++ without foundation? This does not work: mainBundle = CFBundleGetMainBundle();
namespace client {
// Base class for customizing process-type-based behavior.
class ClientApp : public CefApp {
public:
ClientApp();
enum ProcessType {
BrowserProcess,
RendererProcess,
ZygoteProcess,
OtherProcess,
};
// Determine the process type based on command-line arguments.
static ProcessType GetProcessType(CefRefPtr<CefCommandLine> command_line);
protected:
// Schemes that will be registered with the global cookie manager.
std::vector<CefString> cookieable_schemes_;
private:
// Registers custom schemes. Implemented by cefclient in
// client_app_delegates_common.cc
static void RegisterCustomSchemes(CefRefPtr<CefSchemeRegistrar> registrar,
std::vector<CefString>& cookiable_schemes);
void OnBeforeCommandLineProcessing(const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) OVERRIDE;
// CefApp methods.
void OnRegisterCustomSchemes(
CefRefPtr<CefSchemeRegistrar> registrar) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(ClientApp);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_COMMON_CLIENT_APP_H_
Trying to import cocoa/foundation after renaming to .mm:
You're importing Foundation.h when you mean #include <CoreFoundation/CoreFoundation.h>. Foundation is an ObjC API (which is not compatible with C++). Core Foundation is a C API. When you include CoreFoundation, CFBundleGetMainBundle() should be fine. Note the CF at the start that is indicating it's part of Core Foundation, vs NS which indicates Foundation (or AppKit).
There is no need to rename this .mm. As long as you use CoreFoundation, it's fine to be a pure C++ file. Just remember that Core Foundation has its own memory management. There is no ARC. You need to remember to CFRelease anything you obtained using a function with Create or Copy in its name (or that you called CFRetain on. Full details are in the Memory Management Programming Guide for Core Foundation.
I want to build my Dojo JavaScript code that I have carefully structured into packages into a single JavaScript file. I'm a little confused as to how to do it.
For now I have this:
var profile = {
...
layers: {
'app': {
include: [
'dojo/module1',
'dojo/module2',
...,
'dojo/moduleN',
'package2/module1',
'package2/module2',
...,
'package2/moduleN'
]
}
}
...
};
Do I really have to manually add all the modules to the app layer? Can't I just say "all", or better yet, "all referenced"? I don't want to include the dojo/something modul if I don't use it. Also, in my release folder, that's all I would like to have - one file.
So - can this even be achieved? Clean Dojo automatic build of only referenced modules into a single (minified and obfuscated of course) JavaScript file?
Take a look at the examples in the Layers section of this build tutorial:
It’s also possible to create a custom build of dojo.js; this is particularly relevant when using AMD, since by default (for backwards compatibility), the dojo/main module is added automatically by the build system to dojo.js, which wastes space by loading modules that your code may not actually use. In order to create a custom build of dojo.js, you simply define it as a separate layer, setting both customBase and boot to true:
var profile = {
layers: {
"dojo/dojo": {
include: [ "dojo/dojo", "app/main" ],
customBase: true,
boot: true
}
}
};
You can include an entire "app" in a single layer by including the root of that app (or module). Note that if a module in that app is not explicitly required by that app, it would have to be included manually. See the second example in the Layers section in the above tutorial for an illustration of that.
You can also define packages to include in your layers, if you want to change or customize the layout of your project:
packages: [
{name:'dojo', location:'other/dojotoolkit/location/dojo'},
/* ... */
],
layers: {
'dojo/dojo': { include: ['dojo/dojo'] },
/* ... */
}
You don't have to specify all the modules, if the module you add already has dependencies on others. For example, if you include 'app/MainApplication' to a layer, the builder would include all the modules that app/MainApplication depens on. If your MainApplication.js touches everything in your project, everything would be included.
During the build of a layer, dojo parses require() and define() calls in every module. Then it builds the dependency tree. Nls resources are also included.
In your code, you should name your layer as a file in existing package. In my build, it caused errors when I name a layer with a single word. You should code
var profile =
layers: {
'existingPackage/fileName': {
...
}
}
If you want to have exacltly one file, you have to include 'dojo/dojo' in your layer and specify customBase and boot flags.
Dojo always build every package before building layers. You will always have dojo and dijit folders in your release directory containing minified versions of dojo filies in them.
Just copy the layer file you need and delete everything other.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I am just starting up a new project that needs some cross-platform GUI, and we have chosen Qt as the GUI-framework.
We need a unit-testing framework, too. Until about a year ago we used an in-house developed unit-testing framework for C++-projects, but we are now transitioning to using Google Test for new projects.
Does anyone have any experience with using Google Test for Qt-applications? Is QtTest/QTestLib a better alternative?
I am still not sure how much we want to use Qt in the non-GUI parts of the project - we would probably prefer to just use STL/Boost in the core-code with a small interface to the Qt-based GUI.
EDIT: It looks like many are leaning towards QtTest. Is there anybody who has any experience with integrating this with a continous integration server? Also, it would seem to me that having to handle a separate application for each new test case would cause a lot of friction. Is there any good way to solve that? Does Qt Creator have a good way of handling such test cases or would you need to have a project per test case?
You don't have to create separate tests applications. Just use qExec in an independent main() function similar to this one:
int main(int argc, char *argv[])
{
TestClass1 test1;
QTest::qExec(&test1, argc, argv);
TestClass2 test2;
QTest::qExec(&test2, argc, argv);
// ...
return 0;
}
This will execute all test methods in each class in one batch.
Your testclass .h files would look as follows:
class TestClass1 : public QObject
{
Q_OBJECT
private slots:
void testMethod1();
// ...
}
Unfortunately this setup isn't really described well in the Qt documentation even though it would seem to be quite useful for a lot of people.
I started off using QtTest for my app and very, very quickly started running into limitations with it. The two main problems were:
1) My tests run very fast - sufficiently quickly that the overhead of loading an executable, setting up a Q(Core)Application (if needed) etc often dwarfs the running time of the tests themselves! Linking each executable takes up a lot of time, too.
The overhead just kept on increasing as more and more classes were added, and it soon became a problem - one of the goals of unit tests are to have a safety net that runs so fast that it is not a burden at all, and this was rapidly becoming not the case. The solution is to glob multiple test suites into one executable, and while (as shown above) this is mostly do-able, it is not supported and has important limitations.
2) No fixture support - a deal-breaker for me.
So after a while, I switched to Google Test - it is a far more featureful and sophisticated unit testing framework (especially when used with Google Mock) and solves 1) and 2), and moreover, you can still easily use the handy QTestLib features such as QSignalSpy and simulation of GUI events, etc. It was a bit of a pain to switch, but thankfully the project had not advanced too far and many of the changes could be automated.
Personally, I will not be using QtTest over Google Test for future projects - if offers no real advantages that I can see, and has important drawbacks.
To append to Joe's answer.
Here's a small header I use (testrunner.h), containing an utility class spawning an event loop (which is, for example, needed to test queued signal-slot connections and databases) and "running" QTest-compatible classes:
#ifndef TESTRUNNER_H
#define TESTRUNNER_H
#include <QList>
#include <QTimer>
#include <QCoreApplication>
#include <QtTest>
class TestRunner: public QObject
{
Q_OBJECT
public:
TestRunner()
: m_overallResult(0)
{}
void addTest(QObject * test) {
test->setParent(this);
m_tests.append(test);
}
bool runTests() {
int argc =0;
char * argv[] = {0};
QCoreApplication app(argc, argv);
QTimer::singleShot(0, this, SLOT(run()) );
app.exec();
return m_overallResult == 0;
}
private slots:
void run() {
doRunTests();
QCoreApplication::instance()->quit();
}
private:
void doRunTests() {
foreach (QObject * test, m_tests) {
m_overallResult|= QTest::qExec(test);
}
}
QList<QObject *> m_tests;
int m_overallResult;
};
#endif // TESTRUNNER_H
Use it like this:
#include "testrunner.h"
#include "..." // header for your QTest compatible class here
#include <QDebug>
int main() {
TestRunner testRunner;
testRunner.addTest(new ...()); //your QTest compatible class here
qDebug() << "Overall result: " << (testRunner.runTests()?"PASS":"FAIL");
return 0;
}
I don't know that QTestLib is "better" than one framework for another in such general terms. There is one thing that it does well, and that's provide a good way to test Qt based applications.
You could integrate QTest into your new Google Test based setup. I haven't tried it, but based on how QTestLib is architected, it seems like it would not be too complicated.
Tests written with pure QTestLib have an -xml option that you could use, along with some XSLT transformations to convert to the needed format for a continuous integration server. However, a lot of that depends on which CI server you go with. I would imagine the same applies to GTest.
A single test app per test case never caused a lot of friction for me, but that depends on having a build system that would do a decent job of managing the building and execution of the test cases.
I don't know of anything in Qt Creator that would require a seperate project per test case but it could have changed since the last time I looked at Qt Creator.
I would also suggest sticking with QtCore and staying away from the STL. Using QtCore throughout will make dealing with the GUI bits that require the Qt data types easier. You won't have to worry about converting from one data type to another in that case.
Why not using the unit-testing framework included in Qt?
An example : QtTestLib Tutorial.
I unit tested our libraries using gtest and QSignalSpy. Use QSignalSpy to catch signals. You can call slots directly (like normal methods) to test them.
QtTest is mostly useful for testing parts that require the Qt event loop/signal dispatching. It's designed in a way that each test case requires a separate executable, so it should not conflict with any existing test framework used for the rest of the application.
(Btw, I highly recommend using QtCore even for non-GUI parts of the applications. It's much nicer to work with.)
To extend mlvljr's and Joe's solution we can even support complete QtTest options per one test class and still run all in a batch plus logging:
usage:
help: "TestSuite.exe -help"
run all test classes (with logging): "TestSuite.exe"
print all test classes: "TestSuite.exe -classes"
run one test class with QtTest parameters: "TestSuite.exe testClass [options] [testfunctions[:testdata]]...
Header
#ifndef TESTRUNNER_H
#define TESTRUNNER_H
#include <QList>
#include <QTimer>
#include <QCoreApplication>
#include <QtTest>
#include <QStringBuilder>
/*
Taken from https://stackoverflow.com/questions/1524390/what-unit-testing-framework-should-i-use-for-qt
BEWARE: there are some concerns doing so, see https://bugreports.qt.io/browse/QTBUG-23067
*/
class TestRunner : public QObject
{
Q_OBJECT
public:
TestRunner() : m_overallResult(0)
{
QDir dir;
if (!dir.exists(mTestLogFolder))
{
if (!dir.mkdir(mTestLogFolder))
qFatal("Cannot create folder %s", mTestLogFolder);
}
}
void addTest(QObject * test)
{
test->setParent(this);
m_tests.append(test);
}
bool runTests(int argc, char * argv[])
{
QCoreApplication app(argc, argv);
QTimer::singleShot(0, this, SLOT(run()));
app.exec();
return m_overallResult == 0;
}
private slots:
void run()
{
doRunTests();
QCoreApplication::instance()->quit();
}
private:
void doRunTests()
{
// BEWARE: we assume either no command line parameters or evaluate first parameter ourselves
// usage:
// help: "TestSuite.exe -help"
// run all test classes (with logging): "TestSuite.exe"
// print all test classes: "TestSuite.exe -classes"
// run one test class with QtTest parameters: "TestSuite.exe testClass [options] [testfunctions[:testdata]]...
if (QCoreApplication::arguments().size() > 1 && QCoreApplication::arguments()[1] == "-help")
{
qDebug() << "Usage:";
qDebug().noquote() << "run all test classes (with logging):\t\t" << qAppName();
qDebug().noquote() << "print all test classes:\t\t\t\t" << qAppName() << "-classes";
qDebug().noquote() << "run one test class with QtTest parameters:\t" << qAppName() << "testClass [options][testfunctions[:testdata]]...";
qDebug().noquote() << "get more help for running one test class:\t" << qAppName() << "testClass -help";
exit(0);
}
foreach(QObject * test, m_tests)
{
QStringList arguments;
QString testName = test->metaObject()->className();
if (QCoreApplication::arguments().size() > 1)
{
if (QCoreApplication::arguments()[1] == "-classes")
{
// only print test classes
qDebug().noquote() << testName;
continue;
}
else
if (QCoreApplication::arguments()[1] != testName)
{
continue;
}
else
{
arguments = QCoreApplication::arguments();
arguments.removeAt(1);
}
}
else
{
arguments.append(QCoreApplication::arguments()[0]);
// log to console
arguments.append("-o"); arguments.append("-,txt");
// log to file as TXT
arguments.append("-o"); arguments.append(mTestLogFolder % "/" % testName % ".log,txt");
// log to file as XML
arguments.append("-o"); arguments.append(mTestLogFolder % "/" % testName % ".xml,xunitxml");
}
m_overallResult |= QTest::qExec(test, arguments);
}
}
QList<QObject *> m_tests;
int m_overallResult;
const QString mTestLogFolder = "testLogs";
};
#endif // TESTRUNNER_H
own code
#include "testrunner.h"
#include "test1"
...
#include <QDebug>
int main(int argc, char * argv[])
{
TestRunner testRunner;
//your QTest compatible class here
testRunner.addTest(new Test1);
testRunner.addTest(new Test2);
...
bool pass = testRunner.runTests(argc, argv);
qDebug() << "Overall result: " << (pass ? "PASS" : "FAIL");
return pass?0:1;
}
If you are using Qt, I would recommend using QtTest, because is has facilities to test the UI and is simple to use.
If you use QtCore, you can probably do without STL. I frequently find the Qt classes easier to use than the STL counterparts.
I've just been playing around with this. The main advantage of using Google Test over QtTest for us is that we do all our UI development in Visual Studio. If you use Visual Studio 2012 and install the Google Test Adapter you can get VS to recognise the tests and include them in its Test Explorer. This is great for developers to be able to use as they write code, and because Google Test is portable we can also add the tests to the end of our Linux build.
I'm hoping in the future that someone will add support for C++ to one of the concurrent testing tools that C# have, like NCrunch, Giles and ContinuousTests.
Of course, you might find someone writes another adapter for VS2012 that adds QtTest support to Test Adapter in which case this advantage goes away! If anyone is interested in this there's a good blog post Authoring a new Visual studio unit test adapter.
For Visual Studio test adapter tool support with the QtTest framework use this Visual Studio extension: https://visualstudiogallery.msdn.microsoft.com/cc1fcd27-4e58-4663-951f-fb02d9ff3653