You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature request] Ability to serve and run tests against pre-compiled output directory #5378
There is currently no way to serve the site (or run tests) against the result of a previously executed ng build. This is problematic for a few reasons explained in detail below.
This is a continuation of the discussion started here: #4975
Consistency - There are some inconsistencies between ng serve and what ng build places in the dist folder. For instance, ng serve serves everything in the root of the src directory which means that static assets can be loaded from src that will not be available after deployment.
Debugging - Sometimes it's useful to be able to serve the app exactly as it will be deployed. I've used this when debugging AOT related issues that only present at run-time in a production build. There are other options for this scenario, but running simple http server in the dist folder was the easiest option, but I think ng-cli should be able to use it's included server for this instead of me needing to use another http server.
Deployment pipeline - currently my continuous deployment is building the app 3 times. Once each for ng test, ng e2e, ng build. Ideally I could run ng build then run the tests against the code in the dist folder.
Before discussing anything else, I would like to mention that your first point was true a while ago, but has since been fixed in #4691. So files in ./src are not served unless they are truly part of the build.
I agree that there is a need for this sort of functionality, but not as far reaching as you propose.
Unit testing is not a real scenario in my opinion. Build code does not include unit tests, and it doesn't make any sense to try and run outside unit tests over already built code.
The e2e scenario is also a minor issue since you can disable serving via ng e2e --no-serve. After that you can configure a different baseUrl for protractor and it will test whatever you point it at. Admittedly, we don't offer --baseUrl flag but you do offer a --config flag instead to use a different config file.
So as long as you can serve the built version somehow, you can e2e test it right now.
So that leaves us with the matter of consistency and debugging 'real' builds.
You mentioned running a simple http server. But you must agree that is a poor simulacrum of your real server. The only real point of commonality are that it serves files somehow. So the need for consistency is not being fulfilled, and the debugging one only partially.
I think that the very least such a server would need is:
So I argue that simulating ones real server with fidelity is not just a matter of firing up a simple http server.
That is not to say this isn't a real need. It is. And if we had this, there would be a lot of problems that would be caught before the app is deployed somewhere.
So I would like to see such a command in the CLI in the future. Something like ng serve --dir=./dist or ng serve-build. But it needs to be a high-fidelity simulation.
Reacted by Peter Bouda, Vukasin Nikolic, Fabian Wiles, Clayton Bell and Sebastian Kleinschmager
I'm actually running ngServe with most of the criteria you listed today (custom host name, ssl cert, same routing, fallback) this is needed because our app has an oAuth scenario that requires https and a valid hostname in the callback URI.
I'm using IIS in production (I work at Microsoft btw) so I'm happy with just a similar enough http server for e2e tests, and honestly the web pack dev server does fine. We also have a staging deployment and flighting / rollback so the e2e's are just the first line of defense.
I suppose given the criteria you mentioned it might just make more sense to not even use ng to spin up the server because everyone will have their own production server story so building the app then running your own server for E2Es and local prod-like testing makes more sense.
I would like to add an argument. I'm fond of VS Code because it has some great remote debugging possibilities. With the current version of the cli this is no longer possible as the .map files only exist in memory and VS Code needs them physically.
Most compelling to me is the reduction of unnecessary work on CI builds.
In addition, the issue about running against a production-like environment isn't so much about running against the real deployment environment, as it is running against the code that you actually intend to deploy to your server, to then be served to your client (we are, after all, testing client applications that a dumb server just serves up).
When something odd happens in an e2e build, there's little ability to truly introspect what the test is running against, short of obtaining a whole separate environment and deploying code (this is difficult in corporate environments where setting an environment up and/or sharing environments for different purposes, i.e. mock or instrumented code, can be a huge pain in the neck).
Another use case is that doing things like instrumenting code for coverage details before a one-off test run, or as mentioned above, editor configuration, becomes much simpler.
I am very surprised that there's no option for the ng test command to test against an already built app. The main motivation for me is reducing CI build time too as @MonkeyIncinerator noticed.
Is there already someone working on this topic ? I can be a volunteer in case
Reacted by Alexey Krasman, spacem, Sam Miles, monstrege, Tobias Becker, Kevin Brey, Troels Wiberg Jensen, Jacob Patenaude, Philip, Dave and 4 more
To me the most important problem to solve is testing. ng test tests one thing, and what we later run in production comes from ng build. This breaks a basic rule of consistency. Our builds are not trustworthy. We don't know if we tested what is actually in production. It could be something else.
Also, the total build time increases, as we build twice, once for the test, and another for the actual build.
And the test time increases as well, as there is a lot of compilation happening during testing, which we could already had ran with aot.
Reacted by Tobias Becker, Troels Wiberg Jensen, Khalil LAGRIDA, Dominic Wyler, Nick and Adrien Crivelli
Hi, is there any progress on this topic?
I'm working on a project where we have to prove that our binary (aka a docker image containing an Angular app on nginx) is tested (using ng test). We can't build a binary, test a second binary (build by ng test) and then promoting the first (untested) binary to the next stage in our CI/CD.
Any ideas? - Thanks, Markus
To me the primary motivation here is to avoid building twice on CI server, but the added benefit of testing on the same compiled output is compelling as well 😄
Can we get a status on this request?
Reacted by Jacob Patenaude, Andriy Shtanheiev, Leonardo Soares e Silva and Lachlan Heywood
How about a ng build that run internally ng test with an option to skip tests?
Generally I like that idea, however it raises a series of questions I guess, like where do the compiled test files go? Is the build triggered with the tests suitable for the production? Is the code splitting of production and tests even possible in a convenient way? Will ng-packagr then run the tests?
According to this comment (angular/angular#12409 (comment)), the speed problem I mentioned above (#5378 (comment)) has been resolved. The other problems remain. I still have to validate the speed to make sure.
Unit test builds are distinct from typical application builds, using different files (includes test files, doesn't include application bootstrap), so you can't just ng build and then run the tests afterwards. It also doesn't really make sense to do a "test build" without actually running the test, since there's nothing else you could have done with that build anyways. Most of the motivations in this issue seem to be reducing duplicate CI work, and while ng build and ng test do build the app similarly, they are fundamentally incompatible with each other in this way. There's no work that can be meaningfully reused like this.
ng e2e is a little different since we recommend third party builders. End-to-end tests definitely should use some form of your production server (with test data or in a test environment), and the e2e builders should support that. If not, we recommend following up with those maintainers for the support you need.
When it comes to debugging and serving for unit tests, devservers typically differ from prod servers. To be truly identical you need to do use your prod server for testing, which means it should support live reload, sourcemaps, etc. Doing so also means you're using production data for testing, which should generally be mocked. A separate test server with mock data is usually the best way to address this. The only middle ground is if your prod server is effectively a static file server, but at that point using a separate dev server is identical anyways and doesn't really cause any challenges.
Hopefully that helps explain some of our thought process around this. As a result, we don't think there's much value in supporting a test setup that works from a pre-compiled directory.
you can't just ng build and then run the tests afterwards.
Except that you totally could by simply importing from the prod assets when you compile the tests, as if they were a library, instead of treating a 2nd run of compilation as an inherent part of the testing process.
It also doesn't really make sense to do a "test build" without actually running the test, since there's nothing else you could have done with that build anyways.
Tell that to Java and Maven! They've been doing test builds as part of the build process since forever! Yes there is no other use for that code but to run the test, but...uhh...isn't that the only point to writing the test too? The value is that by decoupling the production build, you are assured that your prod assets === assets under test
When it comes to debugging and serving for unit tests, devservers typically differ from prod servers.
Yes, and JVM test runners differ from running from the main, but at least the code under test is the same, and only compiled once!
You're not testing the servers, you're testing the code you wrote, compiled, and are going to deploy. You're confusing a runtime constraint with a compile time constraint.
Anyways, I doubt you're reopening, but I disagree, for the record 😁
Reacted by Troels Wiberg Jensen
angular-automatic-lock-bot commented on Mar 20, 2022
Activity
filipesilva commentedon Mar 13, 2017
Before discussing anything else, I would like to mention that your first point was true a while ago, but has since been fixed in #4691. So files in
./srcare not served unless they are truly part of the build.filipesilva commentedon Mar 13, 2017
I agree that there is a need for this sort of functionality, but not as far reaching as you propose.
Unit testing is not a real scenario in my opinion. Build code does not include unit tests, and it doesn't make any sense to try and run outside unit tests over already built code.
The e2e scenario is also a minor issue since you can disable serving via
ng e2e --no-serve. After that you can configure a differentbaseUrlfor protractor and it will test whatever you point it at. Admittedly, we don't offer--baseUrlflag but you do offer a--configflag instead to use a different config file.So as long as you can serve the built version somehow, you can e2e test it right now.
So that leaves us with the matter of consistency and debugging 'real' builds.
You mentioned running a simple http server. But you must agree that is a poor simulacrum of your real server. The only real point of commonality are that it serves files somehow. So the need for consistency is not being fulfilled, and the debugging one only partially.
I think that the very least such a server would need is:
localhost)--deploy-urland--base-urlto match your build--proxy-config)So I argue that simulating ones real server with fidelity is not just a matter of firing up a simple http server.
That is not to say this isn't a real need. It is. And if we had this, there would be a lot of problems that would be caught before the app is deployed somewhere.
So I would like to see such a command in the CLI in the future. Something like
ng serve --dir=./distorng serve-build. But it needs to be a high-fidelity simulation.itslenny commentedon Mar 14, 2017
I'm actually running ngServe with most of the criteria you listed today (custom host name, ssl cert, same routing, fallback) this is needed because our app has an oAuth scenario that requires https and a valid hostname in the callback URI.
I'm using IIS in production (I work at Microsoft btw) so I'm happy with just a similar enough http server for e2e tests, and honestly the web pack dev server does fine. We also have a staging deployment and flighting / rollback so the e2e's are just the first line of defense.
I suppose given the criteria you mentioned it might just make more sense to not even use ng to spin up the server because everyone will have their own production server story so building the app then running your own server for E2Es and local prod-like testing makes more sense.
DavyDeDurpel commentedon Mar 16, 2017
I would like to add an argument. I'm fond of VS Code because it has some great remote debugging possibilities. With the current version of the cli this is no longer possible as the .map files only exist in memory and VS Code needs them physically.
kfrooney commentedon Dec 12, 2017
I agree for all of the reasons stated above.
Most compelling to me is the reduction of unnecessary work on CI builds.
In addition, the issue about running against a production-like environment isn't so much about running against the real deployment environment, as it is running against the code that you actually intend to deploy to your server, to then be served to your client (we are, after all, testing client applications that a dumb server just serves up).
When something odd happens in an e2e build, there's little ability to truly introspect what the test is running against, short of obtaining a whole separate environment and deploying code (this is difficult in corporate environments where setting an environment up and/or sharing environments for different purposes, i.e. mock or instrumented code, can be a huge pain in the neck).
Another use case is that doing things like instrumenting code for coverage details before a one-off test run, or as mentioned above, editor configuration, becomes much simpler.
Free the compiled assets :-D!
GO3LIN commentedon Jul 17, 2018
I am very surprised that there's no option for the
ng testcommand to test against an already built app. The main motivation for me is reducing CI build time too as @MonkeyIncinerator noticed.Is there already someone working on this topic ? I can be a volunteer in case
Iverson commentedon Aug 21, 2018
Is there any plans to solve that problem?
giggio commentedon Sep 20, 2018
To me the most important problem to solve is testing.
ng testtests one thing, and what we later run in production comes fromng build. This breaks a basic rule of consistency. Our builds are not trustworthy. We don't know if we tested what is actually in production. It could be something else.Also, the total build time increases, as we build twice, once for the test, and another for the actual build.
And the test time increases as well, as there is a lot of compilation happening during testing, which we could already had ran with
aot.markus-heinisch commentedon May 27, 2019
Hi, is there any progress on this topic?
I'm working on a project where we have to prove that our binary (aka a docker image containing an Angular app on nginx) is tested (using ng test). We can't build a binary, test a second binary (build by ng test) and then promoting the first (untested) binary to the next stage in our CI/CD.
Any ideas? - Thanks, Markus
TroelsWibergJensen commentedon Aug 8, 2019
To me the primary motivation here is to avoid building twice on CI server, but the added benefit of testing on the same compiled output is compelling as well 😄
Can we get a status on this request?
klagrida commentedon Jan 17, 2020
How about a ng build that run internally ng test with an option to skip tests?
klemenoslaj commentedon Jan 17, 2020
Generally I like that idea, however it raises a series of questions I guess, like where do the compiled test files go? Is the build triggered with the tests suitable for the production? Is the code splitting of production and tests even possible in a convenient way? Will ng-packagr then run the tests?
giggio commentedon Mar 11, 2020
According to this comment (angular/angular#12409 (comment)), the speed problem I mentioned above (#5378 (comment)) has been resolved. The other problems remain. I still have to validate the speed to make sure.
dgp1130 commentedon Feb 17, 2022
Following up from 2022, I think Filipe's original comment is still pretty accurate.
Unit test builds are distinct from typical application builds, using different files (includes test files, doesn't include application bootstrap), so you can't just
ng buildand then run the tests afterwards. It also doesn't really make sense to do a "test build" without actually running the test, since there's nothing else you could have done with that build anyways. Most of the motivations in this issue seem to be reducing duplicate CI work, and whileng buildandng testdo build the app similarly, they are fundamentally incompatible with each other in this way. There's no work that can be meaningfully reused like this.ng e2eis a little different since we recommend third party builders. End-to-end tests definitely should use some form of your production server (with test data or in a test environment), and the e2e builders should support that. If not, we recommend following up with those maintainers for the support you need.When it comes to debugging and serving for unit tests, devservers typically differ from prod servers. To be truly identical you need to do use your prod server for testing, which means it should support live reload, sourcemaps, etc. Doing so also means you're using production data for testing, which should generally be mocked. A separate test server with mock data is usually the best way to address this. The only middle ground is if your prod server is effectively a static file server, but at that point using a separate dev server is identical anyways and doesn't really cause any challenges.
Hopefully that helps explain some of our thought process around this. As a result, we don't think there's much value in supporting a test setup that works from a pre-compiled directory.
kfrooney commentedon Feb 17, 2022
Except that you totally could by simply
importing from the prod assets when you compile the tests, as if they were a library, instead of treating a 2nd run of compilation as an inherent part of the testing process.Tell that to Java and Maven! They've been doing test builds as part of the build process since forever! Yes there is no other use for that code but to run the test, but...uhh...isn't that the only point to writing the test too? The value is that by decoupling the production build, you are assured that your
prod assets === assets under testYes, and JVM test runners differ from running from the main, but at least the code under test is the same, and only compiled once!
You're not testing the servers, you're testing the code you wrote, compiled, and are going to deploy. You're confusing a runtime constraint with a compile time constraint.
Anyways, I doubt you're reopening, but I disagree, for the record 😁
angular-automatic-lock-bot commentedon Mar 20, 2022
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.