I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Thanks for the request. It may be possible to add support for user command line arguments to the system.
If you are using the preprocessor (i.e. using ‘.pf’ files), then at this time you likely can’t use command line arguments because they are used by include/driver.F90 and internally for a number of special test cases, such as hangs and crashes.
There may be a way to write your own driver, after the fashion of tests/selfTests.F90 in which you can get ahold of an process your command line arguments.
One thought, which may not suit your needs is that if you are free to restructure your program, you might recast your top level as a subroutine with arguments that correspond to your command line arguments. Then you could have your own “main” program get the arguments and pass them into the new top level subroutine driver. You could write unit tests for that new driver subroutine.
Another option involves “mocking” get_command_argument. We were working towards supporting mocks before that research support ended.
Status: open Group: Version 3 (Current) Labels: test Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny Last Updated: Wed Feb 25, 2015 05:11 PM UTC Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Tom just corrected me on a point I made below—the preprocessor and include/driver.F90 are separate concerns. The preprocessor helps with the boilerplate, which you can use with your own customized driver. So it is possible to use the preprocessor.
Thanks for the request. It may be possible to add support for user command line arguments to the system.
If you are using the preprocessor (i.e. using ‘.pf’ files), then at this time you likely can’t use command line arguments because they are used by include/driver.F90 and internally for a number of special test cases, such as hangs and crashes.
There may be a way to write your own driver, after the fashion of tests/selfTests.F90 in which you can get ahold of an process your command line arguments.
One thought, which may not suit your needs is that if you are free to restructure your program, you might recast your top level as a subroutine with arguments that correspond to your command line arguments. Then you could have your own “main” program get the arguments and pass them into the new top level subroutine driver. You could write unit tests for that new driver subroutine.
Another option involves “mocking” get_command_argument. We were working towards supporting mocks before that research support ended.
Status: open Group: Version 3 (Current) Labels: test Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny Last Updated: Wed Feb 25, 2015 05:11 PM UTC Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Status: open Group: Version 3 (Current) Labels: test Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny Last Updated: Wed Feb 25, 2015 05:11 PM UTC Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
I would like to expand on one aspect of Mike’s response.
Presuming that you want to test your module with more than one set of command line inputs, then your current design will almost certainly necessitate having a separate invocation of the testing executable.
pFUnit is designed with the assumption that the systems under test (i.e. the application code) are configurable in some manner. Ideally through procedure arguments, but, if necessary, through global variables (common, module). The command line is not configurable within the application and therefore presents a case that is not really supportable.
There are therefore 3 options:
Option 1: Invoke the test driver multiple times with different command line arguments. There is a some chance that your command line arguments don’t conflict with pFUnit’s command line arguments. If they do conflict, you’ll need to write your own driver, which is easier than it sounds. You would just copy ours and either deactivate or rename the options that we have that conflict with yours.
Option 2: Refactor your design so that there is a single procedure that captures the command line arguments. All other procedures receive the arguments through procedure arguments. You then test all those other procedures in a conventional manner, and skip testing the one procedure that does the actual capturing. Depending on the complexity, the risks for not testing that one procedure are probably reasonable.
Option 3: If you really do want to test the portion of the code that captures the command line arguments, then the strategy to use is “mocking”. What you do is write your own procedure called get_command_argument() that has the same interface as the one in the Fortran standard. Then you also write a subroutine set_command_arguments(…) which sets any necessary global variables in a manner that can be configured through the procedure arguments. (Lots of ways to do this.) Your get_command_argument() then accesses the global variables set by set_command_arguments() rather than from the real command line. Any given test will first call set_command_arguments(…) with the desired settings. The magic is then that you link the driver to the new procedures when running tests and you link to the intrinsic during production. This adds a small amount of complexity in your build.
We’re happy to elaborate on all of these. Option 3, in particular, will seem quite weird until you are used to the concept.
Cheers,
Tom
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First of all, thank you so much for your explanation.
Since the SUT is legacy code as a core library. Refactoring the design would not easy. Mocking sounds great but I don't quite want to implement mock object right now.
In my point of view, Option 1 is more attractive. I have looked through driver.F90. It seems easy to pass command argument to here. But how I can pass those arguments to SUT?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First of all, thank you so much for your explanation.
Since the SUT is legacy code as a core library. Refactoring the design would not easy. Mocking sounds great but I don't quite want to implement mock object right now.
Depending on your priority/interest, we may be interested in setting up an appropriate mock for you. (Has to be on a long timeline, given our current commitments.) Yours is in many ways a better example of the use of mocking than many that we have artificially generated.
In my point of view, Option 1 is more attractive. I have looked through driver.F90. It seems easy to pass command argument to here. But how I can pass those arguments to SUT?
You don’t really need to do anything different than you do for your ordinary production runs. The command line arguments to the pFUnit executable are still command line arguments when they get into your code. Nothing in our code can undo that aspect of invoking the driver. The only concern is if the command line arguments that your code uses interfere with the ones that pFUnit uses.
E.g. if your code needs “-d foo” then putting that on the command line will cause pfunit to enter debugging mode because we interpret “-d” in that manner. I think we ignore all command line arguments that we don’t use, but if not, we may have to do a minor bit of recoding on our end to properly deal with this. (Very low probability — I think.)
Status: open
Group: Version 3 (Current)
Labels: test
Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny
Last Updated: Wed Feb 25, 2015 05:11 PM UTC
Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
There is a ‘case default’ in the select case that goes over the command line arguments. Exiting is the default behavior when an unsupported command line argument is encountered.
To ignore unknown arguments one might try commenting out that default clause. Or one could call or put one’s own command line argument logic there. getCommandLineArgument isn’t called anywhere else in pFUnit.
If the SUT is calling getCommandLineArgument tself, as Tom says, one would have to see if the two treatments of command line arguments interfere.
On Feb 26, 2015, at 3:05 PM, Jinny <jinny2012@users.sf.net <a="" href="mailto:jinny2012@users.sf.net">jinny2012@users.sf.net> wrote:
Tom and Mike,
First of all, thank you so much for your explanation.
Since the SUT is legacy code as a core library. Refactoring the design would not easy. Mocking sounds great but I don't quite want to implement mock object right now.
Depending on your priority/interest, we may be interested in setting up an appropriate mock for you. (Has to be on a long timeline, given our current commitments.) Yours is in many ways a better example of the use of mocking than many that we have artificially generated.
In my point of view, Option 1 is more attractive. I have looked through driver.F90. It seems easy to pass command argument to here. But how I can pass those arguments to SUT?
You don’t really need to do anything different than you do for your ordinary production runs. The command line arguments to the pFUnit executable are still command line arguments when they get into your code. Nothing in our code can undo that aspect of invoking the driver. The only concern is if the command line arguments that your code uses interfere with the ones that pFUnit uses.
E.g. if your code needs “-d foo” then putting that on the command line will cause pfunit to enter debugging mode because we interpret “-d” in that manner. I think we ignore all command line arguments that we don’t use, but if not, we may have to do a minor bit of recoding on our end to properly deal with this. (Very low probability — I think.)
Status: open
Group: Version 3 (Current)
Labels: test
Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny
Last Updated: Wed Feb 25, 2015 05:11 PM UTC
Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Thomas Clune, Ph. D. <Thomas.L.Clune@nasa.gov <a="" href="mailto:Thomas.L.Clune@nasa.gov">Thomas.L.Clune@nasa.gov>
Head ASTG,Code 606
NASA GSFC
MS 610.8 B33-C128
Greenbelt, MD 20771
301-286-4635
Status: open Group: Version 3 (Current) Labels: test Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny Last Updated: Thu Feb 26, 2015 08:05 PM UTC Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Status: open Group: Version 3 (Current) Labels: test Created: Wed Feb 25, 2015 05:11 PM UTC by Jinny Last Updated: Thu Feb 26, 2015 08:05 PM UTC Owner: nobody
I have a module having a lot of get_command_argument call. I need to pass command arguments in order to test those procedures with get_command_argument call. Currently, Running tests.x cannot pass arguments to the test suite.
Thanks for the request. It may be possible to add support for user command line arguments to the system.
If you are using the preprocessor (i.e. using ‘.pf’ files), then at this time you likely can’t use command line arguments because they are used by include/driver.F90 and internally for a number of special test cases, such as hangs and crashes.
There may be a way to write your own driver, after the fashion of tests/selfTests.F90 in which you can get ahold of an process your command line arguments.
One thought, which may not suit your needs is that if you are free to restructure your program, you might recast your top level as a subroutine with arguments that correspond to your command line arguments. Then you could have your own “main” program get the arguments and pass them into the new top level subroutine driver. You could write unit tests for that new driver subroutine.
Another option involves “mocking” get_command_argument. We were working towards supporting mocks before that research support ended.
Mike R.
--
Related
Feature Requests: #38
Tom just corrected me on a point I made below—the preprocessor and include/driver.F90 are separate concerns. The preprocessor helps with the boilerplate, which you can use with your own customized driver. So it is possible to use the preprocessor.
Mike R.
--
Related
Feature Requests: #38
I would like to expand on one aspect of Mike’s response.
Presuming that you want to test your module with more than one set of command line inputs, then your current design will almost certainly necessitate having a separate invocation of the testing executable.
pFUnit is designed with the assumption that the systems under test (i.e. the application code) are configurable in some manner. Ideally through procedure arguments, but, if necessary, through global variables (common, module). The command line is not configurable within the application and therefore presents a case that is not really supportable.
There are therefore 3 options:
Option 1: Invoke the test driver multiple times with different command line arguments. There is a some chance that your command line arguments don’t conflict with pFUnit’s command line arguments. If they do conflict, you’ll need to write your own driver, which is easier than it sounds. You would just copy ours and either deactivate or rename the options that we have that conflict with yours.
Option 2: Refactor your design so that there is a single procedure that captures the command line arguments. All other procedures receive the arguments through procedure arguments. You then test all those other procedures in a conventional manner, and skip testing the one procedure that does the actual capturing. Depending on the complexity, the risks for not testing that one procedure are probably reasonable.
Option 3: If you really do want to test the portion of the code that captures the command line arguments, then the strategy to use is “mocking”. What you do is write your own procedure called get_command_argument() that has the same interface as the one in the Fortran standard. Then you also write a subroutine set_command_arguments(…) which sets any necessary global variables in a manner that can be configured through the procedure arguments. (Lots of ways to do this.) Your get_command_argument() then accesses the global variables set by set_command_arguments() rather than from the real command line. Any given test will first call set_command_arguments(…) with the desired settings. The magic is then that you link the driver to the new procedures when running tests and you link to the intrinsic during production. This adds a small amount of complexity in your build.
We’re happy to elaborate on all of these. Option 3, in particular, will seem quite weird until you are used to the concept.
Cheers,
Tom and Mike,
First of all, thank you so much for your explanation.
Since the SUT is legacy code as a core library. Refactoring the design would not easy. Mocking sounds great but I don't quite want to implement mock object right now.
In my point of view, Option 1 is more attractive. I have looked through driver.F90. It seems easy to pass command argument to here. But how I can pass those arguments to SUT?
On Feb 26, 2015, at 3:05 PM, Jinny jinny2012@users.sf.net wrote:
You don’t really need to do anything different than you do for your ordinary production runs. The command line arguments to the pFUnit executable are still command line arguments when they get into your code. Nothing in our code can undo that aspect of invoking the driver. The only concern is if the command line arguments that your code uses interfere with the ones that pFUnit uses.
E.g. if your code needs “-d foo” then putting that on the command line will cause pfunit to enter debugging mode because we interpret “-d” in that manner. I think we ignore all command line arguments that we don’t use, but if not, we may have to do a minor bit of recoding on our end to properly deal with this. (Very low probability — I think.)
Cheers,
Thomas Clune, Ph. D. Thomas.L.Clune@nasa.gov
Head ASTG,Code 606
NASA GSFC
MS 610.8 B33-C128
Greenbelt, MD 20771
301-286-4635
Related
Feature Requests: #38
There is a ‘case default’ in the select case that goes over the command line arguments. Exiting is the default behavior when an unsupported command line argument is encountered.
To ignore unknown arguments one might try commenting out that default clause. Or one could call or put one’s own command line argument logic there. getCommandLineArgument isn’t called anywhere else in pFUnit.
If the SUT is calling getCommandLineArgument tself, as Tom says, one would have to see if the two treatments of command line arguments interfere.
Related
Feature Requests: #38
I modified the driver file a little bit, now it is being able to pass command arguments to the executable files.
Thanks a lot !
You are welcome and I’m glad it’s working. If convenient, please consider sharing with us your modifications with us. Others may find them useful too.
Cheers!
Related
Feature Requests: #38