Scrum expects cross-functional team members, when developers do not help with the testing part of product backlog items, then they are not cross-functional. Everyone should focus on getting work done, its a team effort.
I get the feeling you guys are doing "Mini waterfall" in short iterations and pushing testing to the end. Its hard to turn around a culture to prevent mini waterfalls, but a Sprint is not a mini waterfall.
Keeping tasks small will help if you have to keep seperate roles between creating code and testing. Testers can start testing after the first tasks are done. Trying using INVEST to define upcoming sprint backlog items to keep them small and testable.
There are always some tasks developers could do during any downtime:
- Write and extend automated (unit) test-cases coverage
- Create spikes for upcoming features in the product backlog
- Improve API documentation
Update
Another possible solution for your problem is a branching strategy.
- Work in feature branches
- Merge features into a test branch
- Merge tested features into a release/sprint branch
This makes sure that the release/sprint branch is always in a releasable state, and that it does not contain andany unfinished work. At the end of sprint you release all finished work and you can continue with any unfinished work in a new sprint.