So let me reiterate what are different sets for first. Training set is to let your algorithm learn its parameters so that it can minimize its loss function based on all the data in the training set.
Validation set is to tune the hyperparameter of the algorithm(there are hyperparameters for most of ML algorithm implementations), it does not do this inside the training process, instead the trained model is used to predict on the validation data to evaluate how good this trained model is. And you variate your hyperparameters in this step so you can find what is the best set of hyperparameters to optimize the model. Therefore your best model kind of "knows" your validation data even it's not directly trained on it. For most of the cases, we are interested in a model that that gives the minimum Expected prediction error, which is the expectation of prediction error given all possible training data sets, however in reality we can only approach this value so that's why we use n-fold cross-validation.
Now test set is to assess the performance of your final trained model, your trained model with best-tuned hyper-parameter is totally oblivious of this data set, so the "test error" can serve to check how good your model can be generalized.
One confusion I encounter is sometimes people mix up validation error and test set error (tho it's not considered to be errorneous to use it interchangeably). I think in one instance validation error can be referred as test error which is the model is sparse therefore validation set is served as test set. Otherwise it's a bit confusing.
I personally do not think it's totally necessary to have a test set, as I read in ESL that n-fold cross validation can be unbiased to the expected prediction error and you can just check error variance to see how stable your model is anyway, so I guess if you have a lot of data, it does not hurt to have a test set.